Multiple versions of PHP on Debian/Ubuntu

For some reason, when you search online for how to setup multiple versions of PHP on your Debian or Ubuntu server you will find many articles that state that you have to compile PHP manually. This is not true, as I will demonstrate. Compiling is not necessary, it’s complicated for less experienced users and requires you to install many additional packages on your server.

Having multiple versions is actually quite easy. You just need to install two prerequisites:

 

1
apt-get install apt-transport-https ca-certificates

Get the GPG key

1
wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg

Add custom repository:

1
echo 'deb https://packages.sury.org/php/ jessie main' >> /etc/apt/sources.list.d/php.list

Update apt cache:

1
apt-get update

And now you are able to install different versions of PHP alongside each other. For example you could install PHP 7.1 and php extension for this version like this:

1
apt-get install php7.1 php7.1-fpm php7.1 php7.1-mysql

PHP 7.1 will be installed to /usr/bin/php7.1 and symlink will be made in /etc/alternatives that will enable you to call this version of PHP from the command line with just ‘php’ command. Other versions you install from sury.org will be set up in similar manner. One thing is worth mentioning here – when setting cron jobs that execute PHP scripts via CLI you should set absolute path (e.g. /usr/bin/php7.0), or the version of PHP will change at some point if you install more version of PHP or upgrade your server and that could potentially cause problems with some PHP applications.

Configuring your web server to use this version of PHP is not that hard and there are multiple ways to do this. For example, this is how I configured Apache for an application that requires PHP 7.1:

1
2
3
<FilesMatch \.php$>
  SetHandler "proxy:fcgi://127.0.0.1:9071"
</FilesMatch>

PHP-FPM is configured to listen to loopback network interface on port 9071 in /etc/php/7.1/fpm/pool.d/www.conf by commenting out the default socket and adding a new entry, like this:

1
2
;listen = /run/php/php7.1-fpm.sock
listen = 127.0.0.1:9071

That’s all there is to it.

Read More

What to do with a very old computer

Recently I obtained an old PC that’s pretty much useless for anything. It has 1.5 GB of RAM, single core CPU and 13 GB hard drive. Even 10 years ago this was pretty weak. But this old machine can still be useful. By adding another network card I made router for my home network, that is also DNS server, file backup server and hopefully something more. Here’s how I’ve set it up:

First off, I started by installing Debian, without GUI since it was not needed and installing some basic software (I have to have vim everywhere). I try to use Ansible for every step of the setup, I keep separate folders with playbooks for each server. That way I also have documentation of what was installed.

During the installation, I chose a static IP, so that I would know where to connect over SSH. I have only one functioning monitor now, which I had to use during the installation, but I wanted to connect it back to my main PC as soon as possible, so everything other than the installation was done over SSH. I configured the network in the following way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# The primary network interface
allow-hotplug eth0
iface eth0 inet static
address 192.168.2.1
netmask 255.255.255.0
network 192.168.2.0
broadcast 192.168.2.255
dns-nameservers 127.0.0.1

# The secondary network interface
allow-hotplug eth1
iface eth1 inet static
address 192.168.1.3
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.1

eth0 is connected to my private network, notice that the gateway is not specified here. Also note that I’ve set the DNS to localhost (more on that later). eth1 is plugged into my ADSL modem.

I wanted DHCP on the private network, although I’m using static addresses for most of the devices. I installed ISC DHCP server:

1
apt install isc-dhcp-server

set INTERFACES=”eth0″ in /etc/default/isc-dhcp-server and configured /etc/dhcp/dhcp.conf like this:

1
2
3
4
5
6
7
option domain-name "milos.lab";
option domain-name-servers 192.168.2.1;
...
subnet 192.168.2.0 netmask 255.255.255.0 {
range 192.168.2.150 192.168.2.199;
option routers 192.168.2.1;
}

Finally, I had to restart the service /etc/init.d/isc-dhcp-server restart, and that was it. If you want to check if it’s up and running, you can see if it’s listening to port 67 (netstat -tulnp).

I also wanted to have local DNS server. I use it for ad blocking (I got list of some 2500 domains) and local name resolution. Query caching is another (yet small) benefit. I chose dnsmasq, bind9 would have been an overkill here and having only one config file is much better option. I’ll write another blog post on how I maintain a database of ad servers and how I generate dnsmasq.conf files automatically.

Now, the main part of the setup, routing. I found very nice script here, that was almost perfect for my case.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/sh

PATH=/usr/sbin:/sbin:/bin:/usr/bin

#
# delete all existing rules.
#
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X

# Always accept loopback traffic
iptables -A INPUT -i lo -j ACCEPT

# Allow established connections, and those not coming from the outside
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state NEW -i eth0 -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

#drop all incoming
iptables -A INPUT -i eth1 -j REJECT

# Allow outgoing connections from the LAN side.
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT

# Masquerade.
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

# Don't forward from the outside to the inside.
iptables -A FORWARD -i eth1 -o eth1 -j REJECT

# Enable routing.
echo 1 > /proc/sys/net/ipv4/ip_forward

My only modification (line 22 here) was to add a rule for rejecting all the incoming traffic. This machine is behind NAT, but (call me crazy if you will) I never put too much trust in embedded devices (backdoors, bugs, no security updates…) and this feels cleaner.

This script must be executable and it goes into /etc/network/if-up.d. It will be executed at each boot.

This was actually the first time I’ve set up routing and DHCP server on a Debian box, and I have to admit that I expected some problems after I’ve rebooted the machine, but to my surprise and delight everything worked. The only problem I have is that it’s heating up the small space where I’ve put it.

This is one of the key benefits of Linux. With this old machine, I would not be able to use recent versions of Windows, I’d be forced to use an old version, XP or Server 2003, which are no longer supported. Instead, I have an OS that is using only a fraction of available resources, it is more secure than Windows will ever be and it’s all free.

Read More