Initial commit

This commit is contained in:
Jeremy Penner 2020-06-14 19:35:18 -04:00
commit 6aa4739a8d
9 changed files with 44464 additions and 0 deletions

51
README.md Normal file
View file

@ -0,0 +1,51 @@
# PHP 5.2.17 for NixOS
I host a community site that is based on Drupal 5, which can't be upgraded without throwing the whole thing in the bin and starting from scratch.
Maybe someday I will do that, but in the meantime, people use it, and I have promised those people that I am not going to delete their stuff.
# Usage
I'm probably doing this wrong! I'm very new to NixOS. Bug reports or pull requests to make things more standard welcome. I think eventually I'll want this to
be a "flake"? I haven't read up on those yet.
Right now I have this sitting in a directory called `php52` beside my nixops server definition. I use it like this:
```nix
{ config, pkgs, lib, ...}:
let
php52 = import ./php52/default.nix { inherit pkgs; };
in
{
require = [ ./php52/module.nix ];
services.php52-fpm.enable = true;
services.nginx.enable = true;
services.nginx.virtualHosts = {
"old-php-site.com" = php52.vhost {
root = "/var/www/old-php-site";
};
"old-drupal-site.com" = php52.vhostDrupal {
root = "/var/www/old-drupal-site";
};
};
}
```
`module.nix` defines an option to enable a systemd service that starts php-fpm on startup, before nginx starts. The `vhost` and `vhostDrupal` functions
take care of setting up secure default rules and connecting .php files to php-fpm. (`vhostDrupal` adds the rewrite rule that makes `/foo` internally map
to `/index.php?q=foo`.)
## Implementation notes
* I include source for all patches and modules directly because unsupported stuff that is a decade past end of life has a tendency to disappear from stable URLs.
* php52-backports-security-20130717.patch is required to build with modern libxml. It came from https://code.google.com/archive/p/php52-backports/downloads.
* I apply both the suhosin _patch_ and the suhosin _extension_, which are apparently totally separate things. The suhosin _extension_ is required for bcrypt
to work. I hacked my Drupal 5 installation to depend on bcrypt (I don't remember what it was doing for password hashing exactly but it wasn't good). So I
bundle it.
* I have no idea what I would need to do to patch PHP 5.2 so that you could actually used multiple extensions derived seperately in the nix store, so it's all
included in one giant derivation that does two builds. I also modify php.ini in place, so you really can't mess with it.
* PHP 5.2 also makes hard assumptions a few places in the `configure` script that a library's headers and its binaries share a parent directory, which under
`nixpkgs` is not true. I work around it by creating trivial derivations that merge the headers and binaries together for `libjpeg` and `libpng`. This is
dumb, but it works.
* PHP 5.2 appears to bundle its own version of `libgd`, and depend on some of its internal functions that have disappeared in more modern incarnations -
I gave up trying to tell it to use nixpkgs' version.

117
default.nix Normal file
View file

@ -0,0 +1,117 @@
{ pkgs ? import <nixpkgs> {}, lib ? import <nixpkgs/lib>, ... }:
with pkgs; let
mergedLib = lib: name:
derivation {
inherit name coreutils;
system = builtins.currentSystem;
builder = "${bash}/bin/bash";
args = [ ./merge.sh "${lib.out}/*" "${lib.dev}/*" ];
};
m_libjpeg = mergedLib libjpeg "m_libjpeg";
m_libpng = mergedLib libpng "m_libpng";
php52 = stdenv.mkDerivation {
name = "php52";
src = ./php-5.2.17.tar.bz2;
patches = [ ./php52-backports-security-20130717.patch ./php-5.2.17-fpm.patch ./suhosin-patch-5.2.16-0.9.7.patch ];
configureFlags = [
"--enable-fastcgi"
"--with-zlib=${zlib.dev}"
"--with-bz2=${bzip2.dev}"
"--enable-calendar"
"--with-curl=${curl.dev}"
"--enable-exif"
"--with-gd"
"--with-mcrypt=${libmcrypt}"
"--with-mysql=${mysql57}"
"--enable-zip"
"--with-pear"
"--enable-force-cgi-redirect"
"--enable-debug"
"--enable-mbstring"
"--enable-fastcgi"
"--with-fpm-log=/var/log/php52-fpm/php-fpm.log"
"--with-fpm-pid=/run/php52-fpm/php-fpm.pid"
"--enable-fpm"
"--with-libxml-dir=${libxml2.dev}"
"--with-jpeg-dir=${m_libjpeg}"
"--with-png-dir=${m_libpng}"
];
postInstall = ''
cp ./php.ini-recommended "$out/lib/php.ini"
tar xf ${./suhosin-0.9.31.tgz}
cd suhosin-0.9.31
PATH="$out/bin:$PATH" phpize
PATH="$out/bin:$PATH" ./configure --enable-suhosin
make install
cd ..
sed -i 's:^extension_dir = .*:extension_dir = "'$("$out/bin/php-config" --extension-dir)'":' "$out/lib/php.ini"
echo "extension=suhosin.so" >> "$out/lib/php.ini"
'';
buildInputs = [ zlib bzip2 curlFull libmcrypt mysql57 libxml2 lzma m_libjpeg m_libpng autoconf automake ];
};
in
php52 // rec {
vhost = cfg: lib.recursiveUpdate {
extraConfig = ''
client_max_body_size 200m;
index index.php index.html index.htm;
'' + cfg.extraConfig or "";
locations = {
"/favicon.ico" = {
extraConfig = ''
log_not_found off;
access_log off;
'';
};
"/robots.txt" = {
extraConfig = ''
allow all;
log_not_found off;
access_log off;
'';
};
"~ \\..*/.*\\.php$" = { return = "403"; };
"~ ^/sites/.*/private/" = { return = "403"; };
# Block access to "hidden" files and directories whose names begin with a
# period. This includes directories used by version control systems such
# as Subversion or Git to store control files.
"~ (^|/)\\." = { return = "403"; };
"~ \\.php$" = {
extraConfig = ''
client_max_body_size 200m;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include ${pkgs.nginx}/conf/fastcgi.conf;
fastcgi_param HTTP_PROXY "";
'';
};
"~ /\.ht" = {
extraConfig = ''
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
deny all;
'';
};
};
} (builtins.removeAttrs cfg [ "extraConfig" ]);
vhostDrupal = cfg: vhost (lib.recursiveUpdate cfg {
locations = {
"/" = { tryFiles = "$uri @rewrite"; };
"@rewrite" = {
extraConfig = ''
# For Drupal 6 and bwlow:
# Some modules enforce no slash (/) at the end of the URL
# Else this rewrite block wouldn't be needed (GlobalRedirect)
rewrite ^/(.*)$ /index.php?q=$1;
'';
};
};
});
}

7
merge.sh Executable file
View file

@ -0,0 +1,7 @@
export PATH=${coreutils}/bin
mkdir $out
for src in "$@"
do
chmod -R +w $out
cp -R $src $out
done

36
module.nix Normal file
View file

@ -0,0 +1,36 @@
{ config, lib, pkgs, ...}@args:
with lib;
let
cfg = config.services.php52-fpm;
php52 = import ./default.nix args;
in {
options.services.php52-fpm = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
If enabled, NixOS will start a PHP 5.2 FastCGI daemon in the background.
'';
};
};
config = {
systemd.services.php52-fpm = mkIf cfg.enable {
wantedBy = [ "multi-user.target" ];
before = [ "nginx.service" ];
environment = {
PHP_FCGI_CHILDREN = "4";
PHP_FCGI_MAX_REQUESTS = "5000";
};
serviceConfig = {
Type = "forking";
PIDFile = "/run/php52-fpm/php-fpm.pid";
ExecStart = "${php52}/bin/php-cgi -x";
User = "nginx";
Group = "nginx";
RuntimeDirectory = "php52-fpm";
LogsDirectory = "php52-fpm";
};
};
};
}

33857
php-5.2.17-fpm.patch Normal file

File diff suppressed because it is too large Load diff

BIN
php-5.2.17.tar.bz2 Normal file

Binary file not shown.

File diff suppressed because it is too large Load diff

BIN
suhosin-0.9.31.tgz Normal file

Binary file not shown.

File diff suppressed because it is too large Load diff