Disclaimer

The views expressed on this blog are my own and do not necessarily reflect the views of my employer.

Monday, November 14, 2016

Play all music files from a local or remote directory via web browser

I blogged about Setting up Raspberry Pi with Apache HTTP server to display files from external hard drive over HTTPS with authentication. The external drive in question has a folder called Music and my objective here is to play all MP3 files from the folder one after another, in a random order. I can click on each file and play them one by one, but that's quite inconvenient. So I decided to use PHP to find all files in the directory and play them using HTML5 Audio tag in a random order. The steps are below (on my Raspberry Pi):

1. $ sudo apt-get update && sudo apt-get upgrade

2. Install PHP: $ sudo apt-get install libapache2-mod-php5 php5 php-pear php5-xcache php5-mysql php5-curl php5-gd

3. Go to DocumentRoot $ cd /var/www/html

4. Create a file for testing $ sudo echo "<?php phpinfo(); ?>" | sudo tee index.php

5. Restart Apache $ sudo service apache2 restart

6. Go to your browser and type x.x.x.x/index.php

If everything works Ok proceed to the next step.

I found it difficult to work with Aliases for this exercise. In my previous note I used

Alias /500all "/media/HD500G"

but now I changed it to

Alias /media/HD500G "/media/HD500G"

(so you can work without Aliases, but I wanted to keep it because I may revert it back).

The next step is to create a music.php file under DocumentRoot that will find the MP3 files from a directory and will play the files. The code is below.

Once you have created the file, change the directory name and go to x.x.x.x/music.php on your web browser.

References:
https://www.stewright.me/2015/08/tutorial-install-apache-php-and-mysql-on-a-raspberry-pi-2/
http://www.webdeveloper.com/forum/showthread.php?352807-PROBLEM-play-all-mp3-files-from-dir-PHP

Sunday, January 17, 2016

Raspberry Pi - expanding root file system

I was playing with a Raspberry Pi 2 Model B for last couple of days. My OS installation notes are here, and after the OS I installed VNC, Samba and Apache HTTP Server. Once I finished these installations and configurations, I noticed the root file system was 98% full. I was using a 64 GB Micro SD card, but the root filesystem was created on a partition of 3.8 GB only. So I needed to expand the root file system.

I found the following tutorial quite useful, it has step-by-step instructions that worked great.
https://www.raspberrypi.org/forums/viewtopic.php?f=51&t=45265

However, the "mkpart" resulted in an error:
Error: The maximum head value is 254.

In order to fix it, I had to reduce the value. Initially I was trying:

(parted) mkpart primary 6,127,57  1946,255,62

that resulted in the error. Error: The maximum head value is 254.

Then I tried reduce the head value to 254:

(parted) mkpart primary 6,127,57  1946,254,62

but still no luck.

But the following finally worked:

(parted) mkpart primary 6,127,57  1945,252,62

Rest of the tutorial worked as-is for me.

Setting up Raspberry Pi with Apache HTTP server to display files from external hard drive over HTTPS with authentication

Devices:
Raspberry Pi 2 Model B (I bought it with a case and charger - Amazon link)
with 64 GB Micro SD card -  Amazon link
AT&amp;T U-verse router 5031NV 

In my last post I detailed how to share files from an external hard drive using Samba. However I wanted to see and play the files from my external hard drive on the web browser and the easiest way to achieve that was by using Apache HTTP Server. This post contains information about setting up the server, using it to list directories and files, and configure HTTPS using OpenSSL.

While writing this post, my external drive is already mounted at /media/HD500G. You can see the details in the "Set up the external hard drive" section in my previous post.

Apache Installation and mapping URL to FileSystem using Alias

1. I installed apache2 and php5 using
$ sudo apt-get install apache2 php5 libapache2-mod-php5

After the installation completed, I created an alias at /etc/apache2/sites-enabled/000-default.conf and

2. added the following to the file:

Also I set the permission for the files in the shared directory:

3. $ sudo chmod -R o+x /media/HD500G

and restarted the service

4. $ sudo service apache2 restart

Apache runs on port 80 for HTTP and port 443 for HTTPS. It's now ready to show the contents of /media/HD500G if you browse http://111.222.333.444/500all (assuming my public IP is 111.222.333.444 and port 80 is open in my router configuration). However please do NOT open the ports in your router at this point as this is very insecure.

More details about port forwarding is described in previous posts about Samba and SSH and VNC. I created a new user defined application for Apache and associated it with ports 80 and 443.

Configure HTTP basic authentication in Apache

Now I wanted to configure Apache so that it will ask for a username and password before showing the contents of /500all. I used the following steps to configure it:

5. Create a directory: # mkdir /etc/htpasswd
6. Set Up the password for user pi: # htpasswd -c /etc/htpasswd/.htpasswd pi
7. Create a new .htaccess file:
# pwd
/media/HD500
# vi .htaccess
# cat .htaccess
AuthType Basic
AuthName "Authentication Required"
AuthUserFile "/etc/htpasswd/.htpasswd"
Require valid-user


8. Edit /etc/apache2/sites-enabled/000-default.conf
So this is what you added in Step-2. Just replace "All" with "AuthConfig" for AllowOverride. And restart apache:

9. $ sudo service apache2 restart

At this point, if you browse http://111.222.333.444/500all it will ask for a username and password. Username is pi, and the password is what you set in step-6. This is slightly more secure than before, but the credentials will be passed over HTTP, so a MITM can see it in clear text. Now we will configure HTTPS to encrypt the communication.

Configure HTTPS and redirect HTTP traffic

10. Create new keys and certificate using OpenSSL.

# pwd
/etc/apache2


11. Enable SSL module

# a2enmod ssl

12.  Add the following to /etc/apache2/sites-enabled/000-default.conf

 13. Redirect all HTTP traffic to HTTPS. Add the following to /etc/apache2/sites-enabled/000-default.conf

14. Restart Apache:
$ sudo service apache2 restart

That's it. Now browsing http://111.222.333.444/500all will redirect you to https://111.222.333.444/500all and it will ask for authentication. Ignore the complaints from the browser, they don't like self-signed certificates (of course for very valid reasons). But now the connection is encrypted and all the contents of the drive are password protected.

Setting up Raspberry Pi with Samba and external hard drive - AT&T U-verse router configuration to make it remotely accessible

Devices:
Raspberry Pi 2 Model B (I bought it with a case and charger - Amazon link)
with 64 GB Micro SD card -  Amazon link
AT&T U-verse router 5031NV


Once I finished OS installation and SSH and VNC configuration, I wanted to access the files I stored in an external Hard drive using Samba on Raspberry Pi.

Set up the external hard drive

Connect the external drive to RP, and run

1. $ sudo fdisk -l

and find the device and note the "Type". If the type is FAT32, proceed to the next step. But if it's "NTFS", install the NTFS driver using

2. $ sudo apt-get install ntfs-3g

The fdisk command will also print the device e.g. /dev/sda1 that we will use in this step. This is to make sure the device is automatically mounted on a pre-decided location e.g. /media/HD500G. In order to do that, I created a new directory

3. # mkdir /media/HD500G

and added a new line at /etc/fstab

5. /dev/sda1    /media/HD500G    ntfs-3f    defaults,noatime    0    0

If your filesystem is FAT, use "vfat" instead of "ntfs-3g".

Then unmount and mount the drive.

$ sudo umount /dev/sda1
$ sudo mount /dev/sda1

And make sure all your files and directories are there.

$ cd /media/HD500G
$ cd ls -la

It might be good idea to spindown the external drive if it's inactive for a while. Use hdparm to do so once it's inactive for 20 minutes.

$ sudo apt-get install hdparm
$ sudo hdparm -S 240 /dev/sda1

Install and configure Samba

Installing Samba is easy: $ sudo apt-get install samba samba-common-bin

In order to configure it to access /media/HD500G, I added the following to /etc/samba/smb.conf:

[media]
comment = Movies and Music
path = /media/HD500G
valid users = pi
force group = users
create mask = 0660
directory mask = 0771
read only = no

The next step will be adding a user account and setting up a password.

$ sudo smbpasswd -a pi

After that, restart the samba services:

$ sudo service smbd restart
$ sudo service nmbd restart


Open Samba ports on your router

This is required to access the Samba share outside my home-network i.e. from anywhere on the internet. The default ports are TCP 139,445 and UDP 137,138.  You can verify the ports by using

# netstat -plunt | grep smbd

Router Configuration:

Go to the configuration page using the web browser. The page URL is usually printed on the router with the default password. If it's not there, run # netstat -rn and look at the default gateway and try that address. It can be something like 192.168.1.xx. If you don't know the password, try username "admin" and password "password" (I know, very poor choice of credentials from router manufacturers).  If nothing works, contact the internet service provider and ask for the details.

Locate the Firewall settings (usually under settings) and find the page that allows you to make changes to applications, pinholes and DMZ. Select the raspberry pi device and proceed to editing the firewall settings for the device. There should be few applications already listed there, if you see Samba server there, select that and add it as hosted applications. Check what ports were opened by that service. If they are same as above (137, 138, 139, 445),then you are all set. You can now use the public IP of the router to access Samba from anywhere on the internet.

In my case, there was no such Samba server listed in the default applications. So I had to add a new user-defined application under firewall settings. I named it "Samba" and associated it with UDP ports 137, 138 and TCP ports 139 and 445. Then I added Samba to the hosted applications list. Now my RP is open to Samba ports and I can use the samba share from anywhere on the internet.

Access Samba share

The following examples assume my public IP address is 111.222.333.444.

From Unix/Mac OS X:
$ sudo mkdir -p /smb/hdd5
$ sudo mount -t smbfs //pi@111.222.333.444/media /smb/hdd5

In this example "media" is what you wrote under [] at /etc/samba/smb.conf

From Windows:

Type the following in the address bar of your web browser -
\\111.222.333.444

Ubuntu:

File Manager -> Connect to Server

Setting up Raspberry Pi with SSH and VNC - AT&T U-verse router configuration to make it remotely accessible

Device:
Raspberry Pi 2 Model B (I bought it with a case and charger - Amazon link)
with 64 GB Micro SD card -  Amazon link
AT&T U-verse router 5031NV

After my first boot, I noticed the SSH service was already installed and enabled. I was able to login from other devices connected to my router. But I also wanted to install VNC for remote access to the desktop. It was fairly straight forward to install and run VNC.

Install: $ sudo apt-get install tightvncserver
Run: $ tightvncserver
Stop: $ tightvncserver -kill :1

After I ran tightvncserver, I was able to access the Raspberry Pi from other devices using VNC Viewer.

The next step involves setting up my AT&T U-verse router 5031NVto enable remote SSH and VNC access outside my home network (i.e. from the internet). In order to do that, the first thing was finding out the ports these services are running on.

SSH was running on standard port 22.

# netstat -plunt | grep ssh
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      496/sshd

tightvnc was running on 5901 nad 6001.

# netstat -plunt | grep tightvnc
tcp        0      0 0.0.0.0:5901            0.0.0.0:*               LISTEN      30583/Xtightvnc
tcp        0      0 0.0.0.0:6001            0.0.0.0:*               LISTEN      30583/Xtightvnc

Router Configuration:

Go to the configuration page using the web browser. The page URL is usually printed on the router with the default password. If it's not there, run # netstat -rn and look at the default gateway and try that address. It can be something like 192.168.1.xx. If you don't know the password, try username "admin" and password "password" (I know, very poor choice of credentials from router manufacturers).  If nothing works, contact the internet service provider and ask for the details.

Locate the Firewall settings (usually under settings) and find the page that allows you to make changes to applications, pinholes and DMZ. Select the raspberry pi device and proceed to editing the firewall settings for the device. There should be few applications already listed there, if you see SSH server and VNC Server select those and add them as hosted applications. Check what ports were opened by those services. If they are same as above (22 for SSH and 5901,6001 for VNC), then you are all set. You can now use the public IP of the router to access via SSH or VNC from anywhere on the internet.

In my case, the VNC ports were different. So I had to add a new user-defined application under firewall settings. I named it "TightVNC" and associated it with ports 5901 and 6001. Then I removed default VNC from the hosted applications list as I didn't want to keep any ports open unnecessarily and added TightVNC to the list instead. Now my RP is open to ports 22, 5901 and 6001. And I can use SSH client and VNC Viewer applications on my phone to access the device from anywhere on the internet.