Commit 01469404 authored by mh's avatar mh
Browse files

add support for php72 and running php through fpm

parent ff51bbdd
# based on https://snuffleupagus.readthedocs.io/config.html#miscellaneous-examples
# Harden the `chmod` function
# sp.disable_function.function("chmod").param("mode").value_r("^[0-9]{2}[67]$").drop();
# Prevent various `mail`-related vulnerabilities
sp.disable_function.function("mail").param("additional_parameters").value_r("\\-").drop();
# Since it's now burned, me might as well mitigate it publicly
sp.disable_function.function("putenv").param("setting").value_r("LD_").drop()
##Prevent various `include`-related vulnerabilities
sp.disable_function.function("require_once").value_r("\.php$").allow();
sp.disable_function.function("include_once").value_r("\.php$").allow();
sp.disable_function.function("require").value_r("\.php$").allow();
sp.disable_function.function("include").value_r("\.php$").allow();
sp.disable_function.function("require_once").drop()
sp.disable_function.function("include_once").drop()
# This will crash f.e. drupbal
# sp.disable_function.function("require").drop()
# sp.disable_function.function("include").drop()
# Prevent `system`-related injections
sp.disable_function.function("system").param("command").value_r("[$|;&`\\n]").drop();
sp.disable_function.function("shell_exec").param("command").value_r("[$|;&`\\n]").drop();
sp.disable_function.function("exec").param("command").value_r("[$|;&`\\n]").drop();
sp.disable_function.function("proc_open").param("command").value_r("[$|;&`\\n]").drop();
# Prevent runtime modification of interesting things
sp.disable_function.function("ini_set").param("var_name").value("assert.active").drop();
sp.disable_function.function("ini_set").param("var_name").value("zend.assertions").drop();
sp.disable_function.function("ini_set").param("var_name").value("memory_limit").drop();
sp.disable_function.function("ini_set").param("var_name").value("include_path").drop();
sp.disable_function.function("ini_set").param("var_name").value("open_basedir").drop();
# Detect some backdoors via environnement recon
sp.disable_function.function("ini_get").param("var_name").value_r("(?:allow_url_fopen|open_basedir|suhosin)").drop();
#sp.disable_function.function("function_exists").param("function_name").value_r("(?:eval|exec|system)").drop();
#sp.disable_function.function("is_callable").param("var").value_r("(?:eval|exec|system)").drop();
# Ghetto sqli hardening
sp.disable_function.function("mysql_query").param("query").value_r("/\\*").drop();
sp.disable_function.function("mysql_query").param("query").value_r("--").drop();
sp.disable_function.function("mysql_query").param("query").value_r("#").drop();
sp.disable_function.function("mysql_query").param("query").value_r(";.*;").drop();
sp.disable_function.function("mysql_query").param("query").value_r("benchmark").drop();
sp.disable_function.function("mysql_query").param("query").value_r("sleep").drop();
# some CMS and ORM's use this to predict the current schema f.e doctrine
#
sp.disable_function.function("mysql_query").param("query").value_r("information_schema").drop();
sp.disable_function.function("mysqli_query").param("query").value_r("/\\*").drop();
sp.disable_function.function("mysqli_query").param("query").value_r("--").drop();
sp.disable_function.function("mysqli_query").param("query").value_r("#").drop();
sp.disable_function.function("mysqli_query").param("query").value_r(";.*;").drop();
sp.disable_function.function("mysqli_query").param("query").value_r("benchmark").drop();
sp.disable_function.function("mysqli_query").param("query").value_r("sleep").drop();
# some CMS and ORM's use this to predict the current schema f.e doctrine
#
sp.disable_function.function("mysqli_query").param("query").value_r("information_schema").drop();
sp.disable_function.function("PDO::query").param("query").value_r("/\\*").drop();
sp.disable_function.function("PDO::query").param("query").value_r("--").drop();
sp.disable_function.function("PDO::query").param("query").value_r("#").drop();
sp.disable_function.function("PDO::query").param("query").value_r(";.*;").drop();
sp.disable_function.function("PDO::query").param("query").value_r("benchmark\\s*\\(").drop();
sp.disable_function.function("PDO::query").param("query").value_r("sleep\\s*\\(").drop();
# some CMS and ORM's use this to predict the current schema f.e doctrine
#
sp.disable_function.function("PDO::query").param("query").value_r("information_schema").drop();
# Ghetto sqli detection
# alot of apps uses the result of mysql_query to check if everythin was right
# sp.disable_function.function("mysql_query").ret("FALSE").drop();
# sp.disable_function.function("mysqli_query").ret("FALSE").drop();
# sp.disable_function.function("PDO::query").ret("FALSE").drop();
#File upload
sp.disable_function.function("move_uploaded_file").param("destination").value_r("\\.ph").drop();
sp.disable_function.function("move_uploaded_file").param("destination").value_r("\\.ht").drop();
# setup php
class php::base {
package{'php':
package{['php','php-fpm']:
ensure => present,
require => Package['apache'],
} -> file{
......@@ -10,6 +10,14 @@ class php::base {
owner => root,
group => 0,
mode => '0644';
'/etc/php-fpm.d':
ensure => directory,
purge => true,
recurse => true,
force => true,
owner => root,
group => 0,
mode => '0644';
}
$php_settings = deep_merge($php::security_settings,deep_merge($php::settings,
......
# manage a php fpm instance
define php::fpm(
Optional[Pattern[/\Aphp\d+\Z/]] $php_inst_class = undef,
Enum['present','absent'] $ensure = 'present',
Stdlib::Compat::Absolute_Path $workdir = "/var/www/vhosts/${name}",
Stdlib::Compat::Absolute_Path $logdir = "/var/www/vhosts/${name}/logs",
Stdlib::Compat::Absolute_Path $tmpdir = "/var/www/vhosts/${name}/tmp/tmp",
Hash $additional_envs = {},
Hash $php_settings = {},
String $run_user = "${name}_run",
String $run_group = $name,
String $scl_prefix = '',
){
include ::systemd::systemctl::daemon_reload
if $php_inst_class {
require "::php::scl::${php_inst_class}"
$etcdir = getvar("php::scl::${php_inst_class}::etcdir")
$basedir = getvar("php::scl::${php_inst_class}::basedir")
$scl_name = "${scl_prefix}${php_inst_class}"
$php_name = $php_inst_class
$binary = "${basedir}/root/usr/sbin/php-fpm"
} else {
$etcdir = '/etc'
$basedir = '/'
$php_name = 'php'
$binary = "/usr/sbin/php-fpm"
}
service{
[ "fpm-${name}.socket",
"fpm-${name}" ]:;
}
file{
[ "${etcdir}/php-fpm.d/${name}.conf",
"/etc/systemd/system/fpm-${name}.socket",
"/etc/systemd/system/fpm-${name}.service",
]:;
} ~> Exec['systemctl-daemon-reload']
if $ensure == 'present' {
File[ "${etcdir}/php-fpm.d/${name}.conf",
"/etc/systemd/system/fpm-${name}.socket",
"/etc/systemd/system/fpm-${name}.service"] {
owner => root,
group => 0,
mode => '0640',
}
File[ "${etcdir}/php-fpm.d/${name}.conf"]{
content => template('php/fpm/conf.erb'),
}
File["/etc/systemd/system/fpm-${name}.socket"]{
content => template('php/fpm/systemd-socket.erb'),
}
File["/etc/systemd/system/fpm-${name}.service"] {
content => template('php/fpm/systemd-service.erb'),
}
Exec['systemctl-daemon-reload'] -> Service["fpm-${name}.socket"]{
enable => false
} -> Service["fpm-${name}"]{
ensure => 'running',
enable => true,
tag => "systemd-${php_name}-fpm"
} -> Service<| title == 'apache' |>
} else {
Service["fpm-${name}"]{
ensure => stopped,
enable => false,
} -> Service["fpm-${name}.socket"]{
enable => false
} -> File[ "${etcdir}/php-fpm.d/${name}.conf",
"/etc/systemd/system/fpm-${name}.socket",
"/etc/systemd/system/fpm-${name}.service"] {
ensure => absent,
}
}
}
# manage an scl php72 installation
class php::scl::php72(
$timezone = $php::scl::params::timezone,
$settings = $php::scl::params::settings,
) inherits php::scl::params {
$basedir = '/opt/remi/php72'
$etcdir = '/etc/opt/remi/php72'
php::scl::phpx{'72':
etcdir => $etcdir,
timezone => $timezone,
settings => $settings,
suhosin_settings => false, # gone with >= php7
}
php::snuffleupagus::base{
'72':
etcdir => $etcdir,
}
}
......@@ -29,22 +29,34 @@ define php::scl::phpx(
}
create_ini_settings($php_settings,$defaults)
if $suhosin_cryptkey {
$default_suhosin_settings = {
'suhosin.session.cryptkey' => sha1("${suhosin_cryptkey}_session_${name}"),
'suhosin.cookie.cryptkey' => sha1("${suhosin_cryptkey}_cookie_${name}"),
if $suhosin_settings {
if $suhosin_cryptkey {
$default_suhosin_settings = {
'suhosin.session.cryptkey' => sha1("${suhosin_cryptkey}_session_${name}"),
'suhosin.cookie.cryptkey' => sha1("${suhosin_cryptkey}_cookie_${name}"),
}
} else {
$default_suhosin_settings = {}
}
} else {
$default_suhosin_settings = {}
}
$php_suhosin_settings = merge(merge($suhosin_settings,
$php::params::suhosin_default_settings),
$default_suhosin_settings)
$suhosin_defaults = {
path => "${etcdir}/php.d/suhosin.ini",
require => Class["::scl::php${name}"],
notify => Service['apache'],
$php_suhosin_settings = merge(merge($suhosin_settings,
$php::params::suhosin_default_settings),
$default_suhosin_settings)
$suhosin_defaults = {
path => "${etcdir}/php.d/suhosin.ini",
require => Class["::scl::php${name}"],
notify => Service['apache'],
}
create_ini_settings({'' => $php_suhosin_settings},$suhosin_defaults)
}
create_ini_settings({'' => $php_suhosin_settings},$suhosin_defaults)
php::apc::settings{"${etcdir}/php.d/apcu.ini": }
file{
"${etcdir}/php-fpm.d":
ensure => directory,
purge => true,
recurse => true,
force => true,
owner => root,
group => 0,
mode => '0644',
}
}
# manage a snuffleupagus
define php::snuffleupagus(
Stdlib::Compat::Absolute_Path $etcdir,
Optional[Enum[String,Array[String]]] $source = undef,
) {
file{
"${etcdir}/snuffleupagus.d/${name}.rules":
ensure => file,
owner => root,
group => 0,
mode => '0644',
require => File["${etcdir}/snuffleupagus.d"],
notify => Service["fpm-${name}"],
}
if $source {
File["${etcdir}/snuffleupagus.d/${name}.rules"]{
source => $source,
}
}
}
# manage snufleupagus baseline
define php::snuffleupagus::base(
Stdlib::Compat::Absolute_Path $etcdir,
){
file{
"${etcdir}/snuffleupagus.d":
ensure => directory,
purge => true,
recurse => true,
force => true,
owner => root,
group => 0,
mode => '0644';
"${etcdir}/snuffleupagus.d/snuffleupagus-base.rules":
source => 'puppet:///modules/php/snuffleupagus/base.rules',
ensure => directory,
owner => root,
group => 0,
mode => '0644';
} ~> Service<| tag == "systemd-php${name}-fpm" |>
}
[global]
pid = /run/fpm-<%= @name %>/pid
error_log = <%= @logdir %>/fpm-error.log
daemonize = no
[<%= @name %>-0]
listen = /run/fpm-<%= @name %>/0.socket
pm = ondemand
pm.max_children = 10
slowlog = <%= @logdir %>/fpm-slow-0.log
env[TMP] = <%= @tmpdir %>
env[TMPDIR] = <%= @tmpdir %>
env[TEMP] = <%= @tmpdir %>
<%= @additional_envs.empty? ? "\n" : @additional_envs.reject{|k,v| (v == :undef) || v.nil? }.keys.sort.collect { |k| "env[#{k}] = #{@additional_envs[k]}" }.join("\n") %>
<%= @php_settings.reject{|k,v| (v == :undef) || v.nil? }.keys.sort.collect { |flag|
dvalue = @php_settings[flag].to_s.downcase
munged_value = if dvalue == 'true'
'on'
elsif dvalue == 'false'
'off'
elsif ['on','off'].include?(dvalue)
dvalue
else
@php_settings[flag]
end
f = ['on','off'].include?(munged_value) ? 'flag' : 'value'
"php_admin_#{f}[#{flag}] = #{munged_value}"
}.join("\n") %>
[Unit]
Description=<%= @name %>'s FastCGI Process Manager
After=syslog.target network.target
[Service]
ExecStart=/usr/bin/scl enable <%= @scl_name %> -- <%= @binary %> --fpm-config=<%= @etcdir %>/php-fpm.d/<%= @name %>.conf
WorkingDirectory=<%= @workdir %>
User=<%= @run_user %>
Group=<%= @run_group %>
Environment="FPM_SOCKETS=/run/fpm-<%= @name %>/0.socket=3"
RuntimeDirectory=fpm-<%= @name %>
PrivateTmp=true
SyslogIdentifier=fpm-<%= @name %>
[Socket]
ListenStream=/run/fpm-<%= @name %>/0.socket
SocketUser=<%= @run_user %>
SocketGroup=<%= @run_group %>
SocketMode=0660
[Install]
WantedBy=sockets.target
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment