I'm trying to create a light automation system with my Raspberry Pi 2, PHP, Python and an Apache server. Unlike some people, I want to be able to access this server from anywhere in the world. The only problem with this, of course, is that if it's made public, anyone would be able to access the server.

This will be a huge security risk.

If anyone knows a way that the server could either be made private or very secure, that would be most appreciated.

I suppose it would be possible to setup a password system, but there could be ways that it could be broken into. This includes.

  • SQL Injections
  • Brute Force Attacks

I'm already trying to avoid brute force attacks from bots by putting my server on a port other than 80. I don't have much experience with apache servers, but if it's possible, I'd like to learn if I could use something to avoid brute force attacks on that port.

An example would that I use Fail2Ban for my SSH servers.

Although this may not be important, I'm running Raspbian on a Raspberry Pi 2 with Apache 2 and PHP 5.

2 Answers 2


I would look into setting up a reverse proxy over ssh. I set this up once many many moons ago. So I can't really give you the steps, I'm sure google can help you out.

Key advantage only one hole opened on the firewall.


Have a look at htpasswd from apache: htpasswd

The steps to create this can be quite confusing, but in the end you can lock out ANY endpoint url/directory on your server with a user/password prompt.

Key notes from this link in case the link changes:


htpasswd /usr/local/etc/apache/.htpasswd-users jsmith

Adds or modifies the password for user jsmith. The user is prompted for the password.
The password will be encrypted using the modified Apache MD5 algorithm. 
If the file does not exist, htpasswd will do nothing except return an error.

htpasswd -c /home/doe/public_html/.htpasswd jane

Creates a new file and stores a record in it for user jane.
The user is prompted for the password.
If the file exists and cannot be read, or cannot be written,
it is not altered and htpasswd will display a message and return an error status.

htpasswd -db /usr/web/.htpasswd-all jones Pwd4Steve

Encrypts the password from the command line (Pwd4Steve) using the crypt() algorithm,
and stores it in the specified file.

Security Considerations

Web password files such as those managed by htpasswd
should not be within the Web server's URI space --
that is, they should not be fetchable with a browser.

This program is not safe as a setuid executable. Do not make it setuid.

The use of the -b option is discouraged,
since when it is used the unencrypted password appears on the command line.

When using the crypt() algorithm,
note that only the first 8 characters of the password are used to form the password.
If the supplied password is longer,
the extra characters will be silently discarded.

The SHA encryption format does not use salting:
for a given password, there is only one encrypted representation.
The crypt() and MD5 formats permute the representation by prepending a random salt string,
to make dictionary attacks against the passwords more difficult.

The SHA and crypt() formats are insecure by today's standards.

I also personally recommend using php pages and wrapping generated html in echo or return blocks. Thereby not exposing any function code to the browser.

Like so (ultra simplistic example, showing only the result of $bar, but not how it was assigned.):

    $bar = 'bar';
    $some_html = '<div>foo '. $bar .'</div>';
    echo $some_html;

Beyond this, for brute force you could have a sql database logging connection attempts from the remote machine by IP and time stamp, blocking repeated attempts within a set time frame..

You would generate a sql entry based on these variables:

$Logip          = $_SERVER['REMOTE_ADDR'];
$lastaccess     = "";

A function that generates a sql log query if desired called loginlog()

Then use some php to fire off the check: This is just an example..

$time_between_access    = 60; /* 1 minute */
if(((time() - $lastaccess) < $time_between_access)) {
    $message = 'Access Denied for: '. $Logip .', time delay not met. Time left: ' . ceil(($time_between_access - (time() - $lastaccess))/60) . ' mins.';
    echo '<script type="text/javascript">alert("Access denied. Spam detected, try again later.");window.location.replace("http://www.some-other-site-here.net");</script>';
    return '';

The reasoning behind the JS popup is, those can trip up generally simplistic written brute force scripts. Then redirect the page to drop session and go to another page for added complication for any automated hack attempts.

Additionally you could lock out all IPs but specific ones to allow connections:

function admin() {
    $iparray = array('x.x.x.x', 'x.x.x.x', 'x.x.x.x');
    if (in_array($_SERVER['REMOTE_ADDR'], $iparray) {
        return true;
    return false;

if(!admin()) {
    echo '<script type="text/javascript">alert("Access denied. Spam detected, try again later.");window.location.replace("http://www.some-other-site-here.net");</script>';

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.