Mappen, bestanden & rechten - 2019 (WordPress)

Uit De Vliegende Brigade
Naar navigatie springen Naar zoeken springen

Op Unix kennen bestanden en mappen een eigenaar plus diverse rechten (schrijven, lezen en executie) voor verschillende partijen (eigenaar, groep, overig) en nog wat liflafjes. Het is een interessant puzzeltje om dat goed in te stellen, waarbij 'goed' afhankelijk is van oa. de context. Welkom bij de ingang van het konijnenhol.

  • Dit artikel heeft voornamelijk betrekking op productie-omgevingen
  • Met bestanden wordt vaak zowel bestanden als mappen bedoeld, omdat deze vaak hetzelfde zijn.

Het problemen

  • Beveiliging: Bestandsinstellingen is primair een beveiligingsprobleem: Rechten wil je zoveel mogelijk beperken, ten einde beveiligingsissues zoveel mogelijk te beperken
  • Gebruiksgemak: Naast veilig, moet een oplossing uiteraard ook werkbaar zijn. Gebruiksgemak is minder een issue voor productie-omgevingen (waar als het goed is, je eigenlijk nooit 'werkt'), dan voor ontwikkel-omgevingen
  • Flexibiliteit: Specifieker: WordPress kan zichzelf updaten. Heel flexibel, maar tegelijkertijd een beveiligings-issue, want een gekraakte WordPress-site kan zichzelf updaten op manieren die je niet wilt
  • Kennis: Misschien eigenlijk wel het grootste issue: De materie rondom bestandsattributen is vrij complex. Vermoedelijk is de kennis van de beheerder van deze materie, nog wel de belangrijkste factor.

Waarschijnlijk komen al deze aspecten tezamen in de vraag wie moet wat kunnen?

Wie moet wat kunnen?

Webserver mag lezen

Het meest voor de hand liggende: De webserver moet de bestanden van (in dit geval) een WordPress-instantie kunnen lezen. Met Webserver, Apache en WordPress bedoel ik in deze context meestal hetzelfde.

Webserver mag niet executeren

  • Ook al staan er flink wat php-bestanden in een WordPress-instantie, toch hoeft er geen enkel bestand het kenmerk x - execute te hebben. Blijkbaar wordt met executable iets anders bedoeld dan wat WordPress nodig heeft - Handig!
  • P.s.: Mappen moeten wel executeerbaar zijn, voor webserver (?) en mezelf, anders werkt commando cd niet.

Beheerder mag lezen

In de praktijk wordt het leven van de beheerder (ikzelf) nogal lastig als ik de bestanden van een instantie niet kan lezen → Beheerder moet kunnen lezen.

Mag WordPress zichzelf updaten?

WordPress kan zichzelf updaten. Da's oa. handig om snel beveiligingslekken te dichten, bv. zero-day exploits. Het heeft echter een vergaande security-consequentie: Apache/WordPress moet dan schrijftoegang hebben tot alle mappen en bestanden (maar geen executie-rechten). Is dat gewenst?

Wat Digital Ocean hierover schrijft:

WordPress has the ability to update itself. That means that somehow, the process probably associated with Apache, 
needs to be able to read and write all files in a WordPress instance

* Is that a desirable situation? It makes a site much more funerable to hacking
* If so, how to implement this? Make the Apache-process owner of all files? Or simply enable ''Others'' to read & write?

...

First, I would strongly recommend not setting your permissions to 777. This is 
a serious security concern. The user wp-user does not exist by default on Ubuntu 
and is likely left over from the host you exported your site from. All your web 
files should be owned by www-data. Assuming your web root remains /var/www/html 
(the default on the WP one-click image) you can fix the ownership with:

chown -Rf www-data.www-data /var/www/html

Ik kies ervoor dat WordPress zichzelf inderdaad mag updaten (lente 2018). Bijkomstig voordeel: Ik hoef geen aparte rechten in te stellen voor mappen zoals Uploads.

Een mogelijk alternatief:

  • Script uitvoeren die de rechten verruimt
  • Updates toepassen
  • Script uitvoeren om rechten weer terug te draaien.

Deze procedure zou zelfs in één kort script kunnen.

Schrijfrechten WordPress specifieke mappen

Indien je hebt besloten dat WordPress zichzelf niet mag updaten, moet je wellicht voor diverse specifieke mappen alsnog schrijftoegang instellen (bv. wp-content/uploads). Aangezien ik ervoor kies dat WordPress zichzelf mag updaten, behandel ik dit niet verder hier.

Update via CLI

Via de terminal (CLI - command line interface) kun je leuke dingen doen met een WordPress-instantie, waaronder updates. Die kan ik doen vanuit m'n eigen beheer-account, of middels sudo -u vanuit het Apache-account (details verderop).

Update via GUI

De WordPress-GUI (dus de site in een browser) is een proces van Apache/WordPress/Webserver. Als die mag schrijven, kun je de site updaten via een browser. Als je WordPress alleen schrijfrechten geeft tot bepaalde mappen (bv. uploads of vertalingen, of plugins), dan kunnen alleen die onderdelen via de GUI bijgewerkt worden.

Nooit Root

Als je ooit sudo nodig hebt om als beheerder iets operationeels te doen, dan klopt er iets niet aan de instellingen. WordPress geeft een waarschuwing als je via de CLI wp gebruikt als beheerder. Voorbeeld:

sudo wp core update
Error: YIKES! It looks like you're running this as root. You probably meant to run this as the user that 
your WordPress install exists under.

If you REALLY mean to run this as root, we won't stop you, but just bear in mind that any code on this 
site will then have full control of your server, making it quite DANGEROUS.

If you'd like to continue as root, please run this again, adding this flag:  --allow-root

If you'd like to run it as the user that this site is under, you can run the following to become the 
respective user:

    sudo -u USER -i -- wp <command>

Oplossing - Diverse mogelijkheden

Er zijn diverse verschillende manieren om dit puzzeltje aan te pakken:

  • Alles is van mij: Alle mappen & bestanden zijn van mij. Handig voor ontwikkelomgevingen, en ook niet onaardig voor productieomgevingen, zolang ik de enige beheerder ben
  • Webserver is eigenaar: Alle mappen & bestanden zijn van het webserver-proces (meestal www-data)
  • Other: Alle mappen & bestanden zijn van x. Nadere instellingen zijn geconfigureerd via o - others
  • Groups: Webserver & beheerders zitten in dezelfde groep. Dat hoeft niet per se www-data' te zijn
  • Geavanceerd: Gebruik een systeem voor rechtenbeheer zoals mountpoint [1].

Oplossing - Webserver + groups

De oplossing die ik sinds lente 2018 toepas:

  • Alle bestanden en mappen zijn van de webserver (www-data)
  • Ik heb mezelf toegevoegd aan de groep 'www-data'
  • Webserver & groep mogen alle bestanden en mappen lezen & schrijven
  • Niemand mag executeren
  • 'Other' mag nix
  • Voor updates via de CLI gebruik ik sudo -u.

Zie script voor details.

Casus: Script lente 2018 - Onwerkbaar

Leuk bedacht, maar niet practisch: Zodra ik niet zelf de eigenaar van bestanden en mappen ben, wordt het heel ingewikkeld om onderhoud te plegen. Dat kan vermoedelijk opgelost worden middels su (omdat je daarmee ook een andere gebruiker kunt worden, www-data in dit geval), maar daar ben ik nog niet

#!/bin/bash
#
###################################################################################

###################################################################################
# Intro & manual
###################################################################################
#
echo " "
echo " "
echo "============================================================"
echo "wp_rights - Set folder & file rights in a WordPress instance"
echo "============================================================"
echo " "
echo "Configure rights for a production WordPress-site."
echo " "
echo "Key ideas"
echo "========="
echo "* WordPress must be able to update itself, hence the Apache"
echo "  process has read and write privileges to all files and"
echo "  folders"
echo "* Admins are added to the group, which also has read and"
echo "  write privileges to all files and folders"
echo "* 'Others' have no privileges at all"
echo "* No execute privileges for files at all"
echo " "
echo "Argument"
echo "========"
echo "Absolute path (optional). If no path is provided, the current"
echo "working directory will be used"
echo " "
echo "Examples"
echo "======="
echo "wp_rights"
echo "wp_rights /var/www/example.com"
echo " "
echo "Details"
echo "======="
echo "* http://wiki.devliegendebrigade.nl/Mappen,_bestanden_%26_rechten_(WordPress)"
echo "* http://wiki.devliegendebrigade.nl/Eigen_scripts"


##############################################################
# Process input arguments
##############################################################
#
echo " "
echo "Processing input arguments..."
echo "============================="

working_dir=$1

# Path provided, or use CWD?
############################
#
if [ -z "$working_dir" ];	then 
	echo "No path provided. Using current working directory (CWD)"
	working_dir=$PWD
	echo "CWD: $working_dir"
else
	echo "Path is provided"	
fi


# Does it point to a WordPress instance?
########################################
#
if [ ! -f "$working_dir/wp-config.php" ]; then
    echo "File $working_dir/wp-config.php not found"
    echo "Seems this is not a Wordpress instance. Exiting"
    exit
else
	echo "Path seems correct"    
fi

echo "Path: $working_dir"


##############################################################
# Set constants
##############################################################
#
echo " "
echo "Set constants..."
echo "============================="

owner="www-data"
group="www-data"

##############################################################
# Set ownership on all files & folders
##############################################################
#
echo " "
echo "Set ownership on all files & folders..."
echo "======================================="

sudo chown -Rv "$owner:$group" $working_dir


##############################################################
# Bottom line: Revoke all privileges
##############################################################
#
echo " "
echo "Bottom line: Revoke all privileges..."
echo "====================================="

sudo chmod -Rv 000 $working_dir


##############################################################
# Make folders executable to user & group
##############################################################
#
echo " "
echo "Make folders executable to user & group..."
echo "=========================================="

sudo chmod -Rv ug+X $working_dir


##############################################################
# Make folders & files readable & writeable to user & group
##############################################################
#
# * Otherwise, WordPress can't update itself
# * More: wiki.devliegendebrigade.nl/Mappen,_bestanden_%26_rechten_(WordPress)
#
echo " "
echo "Make folders & files readable & writeable to user & group..."
echo "============================================================"

sudo chmod -Rv ug+rw $working_dir


##############################################################
# Finished
##############################################################
#
echo " "
echo "Finished"
echo "========"

Casus: Script dec. 2018 - Bot & onveilig

Quick & dirty. Helaas.

#!/bin/bash

echo " "
echo " "
echo "============================================================"
echo "wp_set_rights - Set WordPress file and directory rights"
echo "============================================================"
echo " "
echo "Input argument: Path to a WP installation (optional)"
echo "===================================================="
echo "If no path has been provided, the current working directory"
echo "(cwd) will be used. If the cwd doesn't seem to contain a"
echo "WordPress installation, wp_set_rights will exit"
echo " "
echo "Example"
echo "======="
echo "wp_set_rights /var/www/example.com"
echo " "
echo "NOTICE"
echo "============="
echo "The approach in this routine is crude and unsafe"


###################################################################################
# Process input argument
###################################################################################
#
echo " "
echo "Processing input argument..."
echo "============================="

# Obtain value for path
#####################################
#
path=$1

if [ -z "$path" ]; then
	path=$PWD
	echo "No path has been provided - using cwd..."
else
	echo "Provided path: $path"	
fi	

# Verify path
#####################################
#
if [ ! -f "$path/wp-config.php" ]; then
    echo "File $path/wp-config.php not found"
    echo "Seems this is not a Wordpress instance."
    echo "Exiting"
    echo " "
    exit
else
	echo "File $path/wp-config.php found"
	echo "Path seems correct"
	echo " "
fi


###################################################################################
# Let's get started
###################################################################################
#
#
echo " "
echo "Setting ownership & rights..."
echo "============================="


###################################################################################
# cd
###################################################################################
#
# Just as a safety precaution, but don't rely on it: Use absolute path names in 
# commands instead
#
cd $path


###################################################################################
# Don't set ownership
###################################################################################
#
# Ownership: Ideally, this should be www-data, but that's currently too complicated
# for me → 
# 1. Skip setting ownership entirely
# 2. Unavoidable? Make me the owner


###################################################################################
# Do set ownership
###################################################################################
#
# * Without setting the ownership, I have no idea where I am. First have to settle
#   where we are, than move from there
# * Make it me, how imperfect this solution may be
#
echo "Setting ownership..."
sudo chown -R example:example $path


###################################################################################
# "Other" is not allowed anything
###################################################################################
#
# * Quite useless, as the results depend entirely on who is the owner: "www-data"
#   or myself:
#   * Good change that this doesn't break a site, if www-data is the owner
#   * If I'm the owner myself, this would probably break the site
#
echo "Don't allow 'other' anyting..."
sudo chmod -R o-rwxX $path


###################################################################################
# "Other" - Read, write, cd
###################################################################################
#
# * I want Apache to be able to update sites. So it needs read- & write access to
#   probably everything
# * However, it only requires execute right on directories, not
#   on files
#
# Tests & results (dec. 2018):
#
# * This seems the universal solution for all Wordfence right-related problems
#   I've had: http://wiki.devliegendebrigade.nl/Wordfence
# * This also seems the solution to all UpdraftPlus right-related problems:
#   http://wiki.devliegendebrigade.nl/UpdraftPlus_(WordPress-plugin)
# * Compatible with "wp plugin update --all" (dec. 2018)
# * Compatible with "wp theme update --all" (dec. 2018)
# * Compatible with "wp core update" (dec. 2018)
#
# * Compatibility with "wp language core update" not yet tested
# * Compatibility with "wp wc update" not yet tested
#
echo "Allow 'other' to read, write and change dir..."
sudo chmod -R o+rwX $path


###################################################################################
# "Other" - Deny writing rights to 'other' on the main dir
###################################################################################
#
echo "Deny writing rights to 'other' on the main dir..."
sudo chmod o-w $path


###################################################################################
# Finished
###################################################################################
#
echo " "
echo "Finished"
echo "============================="
echo " "

Casus: Core-update (mei 2019)

Het probleem

Oplossing (vanuit de root van de installatie):

sudo chmod -R o+rwX .

Casus: Upload folder is not writable (nov. 2019)

Complete foutmelding:

Upload folder is not writable. Export and file upload features will not be functional.

Nu te veel werk om te fixen, maar hier zit veel goeds in: https://wordpress.stackexchange.com/questions/155343/upload-folder-is-not-writable-even-when-permissions-are-correct

Zie ook

Bronnen