27 Mar

Remote Control Raspberry via Apache2 Web Server

Control your raspberry pi and its GPIOs via apache2 Web Server from android app or web browser. Including SSL and htaccess security.

remote control your raspberry pi

Remote Control Raspberry via apache2 Web Server: This post guides you to remote control your raspberry pi via https (self-signed SSL certificate) from wherever you want. We show you how to add htaccess security and add commands via php.


Let’s say you have some fancy Raspberry Pi setup at home which  does some home automation (e.g. via GPIOs) or other tasks for you. But how do you remote control your tasks if necessary? My suggestion is a web interface or a simple android smart phone or tablet app (these devices are usually at hand, so there is no need to access you pi directly).

In order to realize a web interface and a smart phone app you need two things.

  1. the configured raspberry web server (1x functional server, 1x user web interface)
  2. the app

This post will guide you to realize the raspberry configuration for an apache2 web server controlling any command you usually execute via the shell.

We need 5 mayor steps:

  1. Install apache2, php5 and other
  2. Setup SSL for transport security
  3. Setup htaccess for login security
  4. Configure a control webpage
  5. Embed the command

This post does not include instructions for a web interface or android app, but we will give you those.

  • A small script for JavaScrip access for a possible QML App is here.

Install apache2, php5 and other

Apache2 is a web server we will apply for this task, (but any other web server with SSL and htaccess could do the same task).

An excellent installation manual can be found on raspberrypi.org. Use this and come back to us afterwards. If you want to do it quick:

sudo apt-get install apache2 -y
sudo apt-get install php5 libapache2-mod-php5 -y

Setup SSL for transport security

On this topic a lot of tutorials can be found in the web, but for apache2 on a raspberry pi with the right site-config and so on … I  prefer the digitalocean.com tutorial, it’s great. But I’ll give you the short version here:

Activate ssl on the apache2 server with

sudo a2enmod ssl

Then create directory and certificate  with

sudo mkdir /etc/apache2/ssl
sudo openssl req -x509 -nodes -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt

and fill out the field accordingly.

Now we create a config file for https requests with

sudo nano /etc/apache2/sites-available/default-ssl

and input this:

<IfModule mod_ssl.c>
NameVirtualHost *:443

<VirtualHost *:443>
    ServerName <YOUR_PIS_HOST_NAME>
    DocumentRoot /var/www/html/

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch +Includes
        Order allow,deny
        Allow from all

    ErrorLog ${APACHE_LOG_DIR}/error.log
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
    SSLEngine on
    SSLCertificateFile    /etc/apache2/ssl/apache.crt
    SSLCertificateKeyFile /etc/apache2/ssl/apache.key
    SSLCertificateChainFile /etc/apache2/ssl/apache.crt

    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +StdEnvVars
    <Directory /usr/lib/cgi-bin>
        SSLOptions +StdEnvVars

Note: Replace <YOUR_PIS_HOST_NAME> with your pi’s hostname or (if you want to access the pi from outside your network) your domain.

Note: On Raspbian W/var/www/html/” , but “/var/www/”.

At this point I will explain something you can’t find in the referenced tutorial. We will add a redirect in case you forget to enter https.

Open the default apache site file

sudo nano /etc/apache2/sites-available/default

and input this:

<VirtualHost *:80>
    ServerName <YOUR_PIS_HOST_NAME>
    Redirect permanent / https://<YOUR_PIS_HOST_NAME>

So all requests to http will be redirected to the previous created https.

Last you hast to run tow commands to add the ssl-site and restart apache2.

sudo a2ensite default-ssl
sudo service apache2 restart

Test it by visiting http://YOUR_PIS_HOST_NAME and https://YOUR_PIS_HOST_NAME. Your browser will warn you, beause the ssl certificate is self-signed, but thats fine.

Setup htaccess for login security

Now create a .htaccess file with

sudo nano /var/www/html/.htaccess

and copy the following code in it

AuthUserFile /var/www/html/.htpasswd
AuthName "Authorization Required"
AuthType Basic
require valid-user

and the according password file with

htpasswd -c /var/www/html/.htpasswd <USERNAME>

and replace <USERNAME> with the user name you want to login later. You will have to chose a password next. Enter it and continue.

(Some tutorials say, that you have to replace

AllowOverride None


AllowOverride All

in /etc/apache2/sites-availabl/default(-sll), but I didn’t need it on Raspbian Jessie with apache2.)

After all restart apache2 with

/etc/init.d/apache2 restart

When you visit your pi on any browser, you get something like this:


Configure a control webpage

A ‘control website’, like I called it here, is the php-page you call when you want to trigger a command. Of course, the calls can be parameterized, but we’ll get to that. While there is the possibility to create a nice looking web page, i recommend to now do this here. The site we are about to create is something you our other users in you home should/will never see. Thus, the only thing our  page will echo is a status / result or something like this.

So our website will be a php site. As we want to remote control our pi, we need to execute some commands.

The easiest way to do so in php is:


or a little advanced with variable input and with output capturing:

exec("my_command $my_input 2>&1", $my_output, $ret_var);

On last thing is parameters. When you call a php script it goes like


and inside the php script you can read it like

$temp = $_GET['my_variable'];

So a simple control page might look like this:

        $inner_state = $_GET['state'];

        // here you can call your funcions to be executed on your raspberry
        exec("echo 'Received ' $inner_state 2>&1", $my_output, $ret_var);

        if ( $ret_var != 0 ) {
                echo -1;
        else {
                foreach($my_output as $item) {
                     echo $item;

Explanation: When I call this script like http://HOSTNAME/control_page.php?state=”Banana 1″ it executes a lame echo command. On our browser you should see a white screen with the text “Received Banana 1”.

But from this point you can call any function you desire. Just be aware that the function will be executed as www-data user. If you want to run command requiring root-rights, you will have to handle this additionally.


We will present you posts on how the code of an simple android app with java or qml might look like soon.

If you like the script or need some help on adapting this to your needs, please leave a comment.


Leave a Reply

Read previous post:
USB Automount Script for Raspberry Pi

When working with a raspberry pi, you might need some USB storage to carry your data. I for example use...