title


Raspberry Pi
[WEB Server]
  • This is for the remote access to the Raspberry Pi. This is not for the public website.
  • The external request is forwarded to the random port number of the Raspberry Pi. It is secured by the Basic Authentication over the SSL (TLS).
  • The request from the internal LAN is connected on port 80. Their requests are divided by the Virtual Host setting.
  • I used the installation from the latest source files for MySQL, Apache and PHP for the security purpose.
[MySQL]
  • Download of the source files
    
    pi@raspberrypi ~ $ git clone https://github.com/mysql/mysql-server.git
    
  • Install Curses because cmake needs it.
    
    pi@raspberrypi ~ $ sudo apt-get install libncurses5-dev
    
  • Install bison because cmake needs it.
    
    pi@raspberrypi ~ $ sudo apt-get install bison
    
  • cmake. Version is 5.7.9. Boost library definition is necessary. Download enable definition is necessary.
    
    pi@raspberrypi ~ $ cd mysql-server/
    pi@raspberrypi ~/mysql-server $ mkdir release
    pi@raspberrypi ~/mysql-server $ cd release/
    pi@raspberrypi ~/mysql-server/release $ cmake .. -DDOWNLOAD_BOOST=1 -DWITH_BOOST=./boost -DENABLE_DOWNLOADS=1 -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci
    
  • gcc version 4.6(4.6.2) will get the error in lf_alloc-pin.cc compilation. gcc version 4.8(4.8.2) also get the error in item_geofunc_setops.cc compilation. gcc version 4.7(4.7.2) is ok.
    
    pi@raspberrypi ~ $ sudo apt-get install gcc-4.7
    pi@raspberrypi ~ $ sudo apt-get install g++-4.7
    pi@raspberrypi ~ $ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.7 47 --slave /usr/bin/g++ g++ /usr/bin/g++-4.7 --slave /usr/bin/gcov gcov /usr/bin/gcov-4.7
    pi@raspberrypi ~ $ sudo update-alternatives --config gcc
    pi@raspberrypi ~ $ gcc -v
    ...
    gcc version 4.7.2 (Debian 4.7.2-5+rpi1)
    
  • make. It took 6 hours.
    
    pi@raspberrypi ~/mysql-server/release $ make
    
  • Install
    
    pi@raspberrypi ~/mysql-server/release $ sudo make install
    
  • Make configration file /usr/local/mysql/my.cnf.
    mysqld will look for the my.cnf by the following order.
    /etc/my.cnf
    /etc/mysql/my.cnf
    /usr/local/mysql/etc/my.cnf
    ~/.my.cnf
    But, "/usr/local/mysql/support_files/mysql.server" which will be copied to "/etc/init.d" uses "$basedir/my.cnf". So, I put the "my.cnf" in $basedir(=/usr/local/mysql) and I put the link file in "/etc/mysql/".
    
    [client]
    port            = 3306
    socket          = /var/run/mysqld/mysqld.sock
    default-character-set=utf8
    
    [mysqld]
    user            = mysql
    pid-file        = /var/run/mysqld/mysqld.pid
    socket          = /var/run/mysqld/mysqld.sock
    port            = 3306
    basedir         = /usr/local/mysql
    datadir         = /usr/local/mysql/data
    tmpdir          = /tmp
    character-set-server=utf8
    skip-character-set-client-handshake
    bind-address            = 127.0.0.1
    
  • Initialization. It displays the temporary password. This password will be necessary later.
    
    pi@raspberrypi ~/mysql-server/release $ groupadd mysql
    pi@raspberrypi ~/mysql-server/release $ useradd -r -g mysql mysql
    pi@raspberrypi ~/mysql-server/release $ cd /usr/local/mysql
    pi@raspberrypi /usr/local/mysql $ sudo chown -R mysql .
    pi@raspberrypi /usr/local/mysql $ sudo chgrp -R mysql .
    pi@raspberrypi /usr/local/mysql $ sudo bin/mysqld --initialize --user=mysql
    ...
    2015-XX-XXTXX:XX:XX.XXXXXXZ X [Note] A temporary password is generated for root@localhost: **********
    pi@raspberrypi /usr/local/mysql $ sudo bin/mysql_ssl_rsa_setup
    pi@raspberrypi /usr/local/mysql $ sudo chown -R root .
    pi@raspberrypi /usr/local/mysql $ sudo chown -R mysql data
    pi@raspberrypi /usr/local/mysql $ sudo cp support-files/mysql.server /etc/init.d/mysql
    pi@raspberrypi /usr/local/mysql $ sudo update-rc.d mysql defaults
    pi@raspberrypi /usr/local/mysql $ sudo service mysql start
    
  • Add /usr/local/mysql/bin to PATH. /home/pi/.profile
    
    if [ -d "/usr/local/mysql/bin" ] ; then
        PATH="/usr/local/mysql/bin:$PATH"
    fi
    
  • Change Password from the temporary password to the new passsword.
    
    pi@raspberrypi ~ $ mysqladmin -p -u root password
    Enter password:
    New password:
    Confirm new password:
    Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety.
    pi@raspberrypi ~ $
    
  • Check MySQL function and add new MySQL user
    
    pi@raspberrypi ~ $ mysqlshow -p -u root
    Enter password:
    +--------------------+
    |     Databases      |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    +--------------------+
    pi@raspberrypi ~ $ mysql -p -u root
    Enter password:
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 2
    Server version: 5.7.9 Source distribution
    
    Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql> create user 'apache'@'localhost';
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> grant select,insert,update,delete on *.* to 'apache'@'localhost';
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> create database home;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> use `home`
    Database changed
    mysql> create table `personal` ( `id` int(10) default NULL, `name` char(100) default NULL );
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> quit
    Bye
    pi@raspberrypi ~ $ mysql -u apache home
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 23
    Server version: 5.7.9 Source distribution
    
    Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql> insert into personal
        -> values ('10', 'name');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from personal;
    +------+------+
    | id   | name |
    +------+------+
    |   10 | name |
    +------+------+
    1 row in set (0.00 sec)
    
[Apache2]
  • Download the source files from http://httpd.apache.org/. Extract that after FTP to Raspberry Pi.
    
    pi@raspberrypi ~/apache2 $ tar xvfz httpd-2.4.17.tar.gz
    
  • Apache Portable Runtime library is necessary. It includes APR and APR-util. http://apr.apache.org/ Make the directory apr and apr-util under the srclib. Extract apr and apr-util in each directory.
    
    pi@raspberrypi ~/apache2/httpd-2.4.17/srclib/apr $ tar xvfz apr-1.5.2.tar.gz
    pi@raspberrypi ~/apache2/httpd-2.4.17/srclib/apr $ mv -i apr-1.5.2/* .
    pi@raspberrypi ~/apache2/httpd-2.4.17/srclib/apr-util $ tar xvfz apr-util-1.5.4.tar.gz
    pi@raspberrypi ~/apache2/httpd-2.4.17/srclib/apr-util $ mv -i apr-util-1.5.4/* .
    
  • configure. Because PHP web site strongly recommends not to use a thread type MPM, define "--enable-mpms-shared=all" to prepare the shared prefork library.
    
    pi@raspberrypi ~/apache2/httpd-2.4.17 $ ./configure --enable-modules=all --enable-mods-shared=all --with-included-apr --enable-mpms-shared=all
    
  • make. There is no progress information display. it takes around 30 minutes.
    
    pi@raspberrypi ~/apache2/httpd-2.4.17 $ make
    
  • install
    
    pi@raspberrypi ~/apache2/httpd-2.4.17 $ sudo make install
    
  • /usr/local/apache2/conf/httpd.conf
    
    ServerRoot "/usr/local/apache2"
    Listen 80
    Listen xxxxx # for port forwarding.
    LoadModule mpm_prefork_module modules/mod_mpm_prefork.so # select Prefork
    LoadModule authn_core_module modules/mod_authn_core.so
    LoadModule authz_host_module modules/mod_authz_host.so
    LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
    LoadModule authz_user_module modules/mod_authz_user.so
    LoadModule authz_core_module modules/mod_authz_core.so
    LoadModule access_compat_module modules/mod_access_compat.so
    LoadModule auth_basic_module modules/mod_auth_basic.so
    LoadModule reqtimeout_module modules/mod_reqtimeout.so
    LoadModule filter_module modules/mod_filter.so
    LoadModule mime_module modules/mod_mime.so
    LoadModule log_config_module modules/mod_log_config.so
    LoadModule env_module modules/mod_env.so
    LoadModule headers_module modules/mod_headers.so
    LoadModule setenvif_module modules/mod_setenvif.so
    LoadModule version_module modules/mod_version.so
    LoadModule ssl_module modules/mod_ssl.so
    LoadModule unixd_module modules/mod_unixd.so
    LoadModule status_module modules/mod_status.so
    LoadModule autoindex_module modules/mod_autoindex.so
    LoadModule dir_module modules/mod_dir.so
    LoadModule alias_module modules/mod_alias.so
    LoadModule php5_module        modules/libphp5.s
    <IfModule unixd_module>
    User xxxxxxx # This user account has an access permission of DocumentRoot directory only.
    Group xxxxxxx
    </IfModule>
    
    <IfModule dir_module>
        DirectoryIndex index.html index.htm index.php
    </IfModule>
    
    <Files ".ht*">
        Require all denied
    </Files>
    
    <Files "*.log">
        Require all denied
    </Files>
    
    ErrorLog "logs/error_log"
    LogLevel warn
    
    <IfModule log_config_module>
        LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
        LogFormat "%h %l %u %t \"%r\" %>s %b" common
        <IfModule logio_module>
          # You need to enable mod_logio.c to use %I and %O
          LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
        </IfModule>
    </IfModule>
    
    <IfModule mime_module>
        TypesConfig conf/mime.types
        AddType application/x-compress .Z
        AddType application/x-gzip .gz .tgz
    </IfModule>
    
    SSLRandomSeed startup builtin
    SSLRandomSeed connect builtinSSLCipherSuite HIGH:MEDIUM:!MD5:!RC4
    SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4
    SSLHonorCipherOrder on
    SSLProtocol all -SSLv3
    SSLProxyProtocol all -SSLv3
    SSLPassPhraseDialog  builtin
    SSLSessionCache shmcb:/usr/local/apache2/logs/ssl_scache(512000)
    SSLSessionCacheTimeout  300
    
    Include conf/extra/httpd-vhosts.conf # Vertual host setting is in the include file.
    
    <FilesMatch \.php$>
        SetHandler application/x-httpd-php
    </FilesMatch>
    
  • /usr/local/apache2/conf/extra/httpd-vhosts.conf
    Vertual Host settings. I ignored the warning message "AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message".
    
    <VirtualHost 192.168.1.10:80>
            ServerAdmin email
            DocumentRoot /home/www
            <Directory />
                    Options FollowSymLinks
                    AllowOverride None
            </Directory>
            <Directory /home/www/>
                    Options FollowSymLinks
                    AllowOverride None
                    Order allow,deny
                    allow from all
            </Directory>
            ErrorLog "logs/error0.log"
            LogLevel warn
            CustomLog "logs/access0.log" combined
    </VirtualHost>
    
    <VirtualHost 192.168.1.10:xxxxx>
            ServerAdmin xxxxxxx
            DocumentRoot /home/www/pi
            SSLEngine on
            SSLCertificateFile /usr/local/apache2/conf/ssl/server.crt
            SSLCertificateKeyFile /usr/local/apache2/conf/ssl/server.key
            <Directory />
                    Options FollowSymLinks
                    AllowOverride None
            </Directory>
            <Directory /home/www/pi>
                    SSLrequireSSL
                    Options FollowSymLinks
                    AllowOverride None
                    Order allow,deny
                    allow from all
                    AuthUserFile /home/www/pi/.htpasswd
                    AuthGroupFile /dev/null
                    AuthName "INPUT ID and PASSWORD"
                    AuthType Basic
                    require valid-user
            </Directory>
    
            ErrorLog "logs/error.log"
            LogLevel warn
    
            CustomLog "logs/access.log" combined
    </VirtualHost>
    
[SSL]
  • Make Certificate
    
    pi@raspberrypi /usr/local/apache2/conf $ sudo chmod 777 ssl
    pi@raspberrypi /usr/local/apache2/conf/ssl $ openssl genrsa -des3 2048 > server.key
    Generating RSA private key, 2048 bit long modulus
    .........................................+++
    ........+++
    e is 65537 (0x10001)
    Enter pass phrase:
    Verifying - Enter pass phrase:
    pi@raspberrypi /usr/local/apache2/conf/ssl $ openssl req -new -key server.key > server.csr
    Enter pass phrase for server.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) [AU]:JP
    State or Province Name (full name) [Some-State]:Tokyo
    Locality Name (eg, city) []:xxxxx
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:Private
    Organizational Unit Name (eg, section) []:Home
    Common Name (e.g. server FQDN or YOUR name) []:ip address
    Email Address []:xxxxxxxxxx
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    pi@raspberrypi /usr/local/apache2/conf/ssl $ openssl x509 -in server.csr -days 3650 -req -signkey server.key > server.crt
    Signature ok
    subject=/C=JP/ST=Tokyo/L=*****/O=Private/OU=Home/CN=***.***.***.***/emailAddress=*@*.*.*
    Getting Private key
    Enter pass phrase for server.key:
    pi@raspberrypi /usr/local/apache2/conf $ sudo chmod 700 ssl
    
[PHP]
  • Download the source files from http://php.net/downloads.php Extract that after FTP to Raspberry Pi.
    
    pi@raspberrypi ~/php $ tar xvfz php-5.6.15.tar.gz
    
  • Install libxml2-dev for the missing xml2-config error.
    
    pi@raspberrypi ~ $ sudo apt-get install libxml2-dev
    
  • configure.
    
    pi@raspberrypi ~/php/php-5.6.15 $ ./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-mysqli --enable-mbstring
    
  • make. It takes around 40 minutes.
    
    pi@raspberrypi ~/php/php-5.6.15 $ make
    
  • Install
    
    pi@raspberrypi ~/php/php-5.6.15 $ sudo make install
    
  • copy php.ini
    
    pi@raspberrypi ~/php/php-5.6.15 $ sudo cp -i php.ini-production /usr/local/lib/php.ini
    
  • modify php.ini.
    
    session.save_path = "/var/session"
    mbstring.internal_encoding = UTF-8
    mbstring.http_input = UTF-8
    mbstring.http_output = UTF-8
    mbstring.substitute_character = "?";
    
[cron]
  • Cron is used for the copy of the access log file to DocumentRoot. The direct access to *.log is denied by 'Required' directive in httpd.conf.
    
    # /etc/cron.d/accesslog
    
    # Copy accesslog every 30 minutes
    05,35 *     * * *     root   cp /usr/local/apache2/logs/access.log /home/www/pi/xxxxx.log; chmod 666 /home/www/pi/xxxxx.log
    06,36 *     * * *     root   cp /var/log/user.log /home/www/pi/xxxxx.log; chmod 666 /home/www/pi/xxxxx.log
    
[index.php]
  • The picture and the movies are generated by the monitoring camera system in the DocumentRoot.
  • Add links to the movie files.
  • Display the previous external access and the error logs from the log files copied by cron.
  • /home/www/pi/index.php
    
    <?php
    
    date_default_timezone_set("Asia/Tokyo");
    $work =<<<HTM1
    <html>
    <head>
    <title>HOME</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    </head>
    <body>
    <center>
    <img src="000.jpg"><br>
    
    HTM1;
    
    print($work);
    printf("%s<br>\n", date("F d Y H:i:s.", filemtime("000.jpg")));
    
    $access = fopen("xxxxx.log", "r");
    if($access){ 
      $preip="";
      while ($line = fgets($access)) { 
        $logarray1 = preg_split("/\"/", $line);
        $logarray2 = preg_split("/[\s,]+/", $line);
        if($preip != $logarray2[0] && substr($logarray2[0],0,7)!="192.168"){
          $work=sprintf("%s %s %s", substr($logarray2[3],1), $logarray2[0],$logarray1[count($logarray1)-2]);
          $work=htmlspecialchars($work);
        }
        $preip = $logarray2[0];
      } 
      print($work);
      print("<br>\n");
    } 
    fclose($access);
    
    $userlog = fopen("xxxxx.log", "r");
    if($userlog){
      while ($line = fgets($userlog)) {
        if(stristr($line,"Error")!=FALSE){
          $work=htmlspecialchars($line);
          print($work);
          print("<br>\n");
        }
      }
    }
    fclose($userlog);
    
    $filename="000.3gp";
    
    for ($i=0;$i<20;$i++){
      $filename = sprintf("%03d.3gp", $i);
      if( file_exists($filename) ){
        printf("<a href='%s'>%s</a>(%s %dKB)<br>\n", $filename, $filename, date("m/d H:i:s.", filemtime($filename)), filesize($filename)/1024);
      }
    }
    
    for ($i=0;$i<20;$i++){
      $filename = sprintf("%03d.avi", $i);
      if( file_exists($filename) ){
        printf("<a href='%s'>%s</a>(%s %dKB)<br>\n", $filename, $filename, date("m/d Y H:i:s.", filemtime($filename)), filesize($filename)/1024);
      }
    }
    
    $work =<<<HTM2
    </center>
    </body>
    </html>
    HTM2;
    
    print($work);
    
    ?>