Wordpress core update error (without FTP) - tgz install [SOLVED]

NethServer Version: CentoOS 7 - 7.6.1810
Module: nethserver-httpd ???
Wordpress: Standard tgz install of Wordpress 5.1.1
PHP: 5.6 (via nethserver-php-scl)

Hi there,

first post: First things first :wink: -> thanks for this great peace of software!

I am coming from Zentyal, but had troubles updating the system over the last years between versions. So I decided to switch. I decided to go with Nethserver because - as a nerd - I see a lot of potential in the concept (e-smith) and love the community approach. I am mainly working with Ubuntu, but I can deal with any Linux out there (we are using a lot of SuSE for SAP Software at work) :wink:

Description of problem
Lets finally face the problem: I cannot make core wordpress updates from within wordpress (no ftp).

I really hope this is no duplicate post, but I did not find a solution in the forum or the net which fulfilled my needs concerning security and the manual installation method of wordpress.

Wordpress landscape and directory structure
I am not and will not use the nethserver-wordpress module. I have multiple domains and installations with simple plain tgz installations of wordpress within the vhost directory:

/var/lib/nethserver/vhost/domainX, /domainY, /domainZ.

Updates are taken with wordpress automatically.

So far so good. I copied over the old database and directory over and did:

# cd /var/lib/nethserver/vhost/
chown -R ftp:apache domainX
chmod -R +s domainX

This gives me:

 # tree domainX
β”œβ”€β”€ [drwsr-sr-x]  wp-admin
β”‚   β”œβ”€β”€ [drwsr-sr-x]  css
β”‚   β”œβ”€β”€ [drwsr-sr-x]  [...]
β”‚   └── [drwsr-sr-x]  user
β”œβ”€β”€ [drwsr-sr-x]  wp-content
β”‚   β”œβ”€β”€ [drwsr-sr-x]  languages
β”‚   β”œβ”€β”€ [drwsr-sr-x]  plugins
β”‚   β”œβ”€β”€ [drwsr-sr-x]  themes
β”‚   β”œβ”€β”€ [drwsr-sr-x]  upgrade
β”‚   └── [drwsr-sr-x]  uploads
└── [drwsr-sr-x]  wp-includes
    β”œβ”€β”€ [drwsr-sr-x]  blocks
    β”œβ”€β”€ [drwsr-sr-x]  [...]
    └── [drwsr-sr-x]  widgets

virtualhosts.conf
For security and compatibility reasons I added the following to the

  # vim /etc/httpd/conf.d/virtualhosts.conf 
<VirtualHost *:443>
   DocumentRoot "/var/lib/nethserver/vhost/domainX"

# 30directory -- basic directory setup
<Directory /var/lib/nethserver/vhost/domainX>

# 35directoryWorpressWPConfigLocalhost
  <Files wp-config.php>
       Require ip 127.0.0.1
  </Files>

  <RequireAll>
    # access public
    Require all granted
    # authentication disabled
  </RequireAll>
  [...]
</Directory>

#70directory
<Directory "/var/lib/nethserver/vhost/domainX/wp-admin">
   <Files wp-install.php>
       Require ip 127.0.0.1
   </Files>
</Directory>
</VirtualHost>

I also removed these settings (<Files>) - without succes. This is not the problem.

What works OK
I can update plugins, install themes, upload pictures. Everything is fine. Exept the following …

Problem 2: prompt for FTP settings on core update
Because the β€œuse ftp for update” settings page came up I tried to

# less  wp-config.php 
/** Auto Update without FTP */
define('FS_METHOD', 'direct');

Problem 2: Update of wordpress core

Nevertheless, when I start the update I will run into trouble. The download starts successfully, as will the unpack and check. But then the update fails due to copy issues.

Download ..  https://downloads.wordpress.org/release/de_DE/wordpress-5.2.zip …
Unpack ...
Check ...
Prepare install …

Update Failed: The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.

wp-login.php, wp-settings.php, wp-includes/canonical.php, wp-includes/admin-bar.php, wp-includes/script-loader.php, wp-includes/cache.php, wp-includes/[a lot of other files]

Installation went wrong

Expectations for solution
To solve the problems I have concrete perception what should be

  1. I don’t want to bore security holes into my server. So the original WP file and directory permissions should be preserved.
  2. I don’t want and cannot use FTP due to security issues (and it does not work either).
  3. I don’t want to move the installations outside /var/lib/nethserver/vhost
  4. I don’t want to use static httpd.conf files for each vhost - I like to use the e-smith method! That’s why I switched to nethserver.
  5. I already said: no nethserver-wordpress module

So please don’t post such solutions here although they might be well-meant :slight_smile:

Solution?

Here I will post the solution … :wink:

[UPDATE 2019-05-18 - GMT 18:00 h]

Thanks all for you valuable input! Here is my solution:

FTP: Andre suggested to disable FTP in nethserver interface. I did not have to do this. It is enough to disable it in the corresponding virtual host.

Ownership:

So I did:

chown -R apache:apache /var/lib/nethserver/vhost/domainX

More security is good, and it works:

chmod -R o-rwx /var/lib/nethserver/vhost/domainX

VirtualHost - /etc/httpd/conf.d/virtualhosts.conf

Yepp, did it. I want it to be autogenerated with e-smith. So I created some e-smith keys because I wanted to get as much flexibility a possible:

#tree /etc/e-smith/templates-custom/httpd/vhost-extra
.
β”œβ”€β”€ 20forcessl_redirect
β”œβ”€β”€ 30directory20optionsFollowSymlinks
β”œβ”€β”€ 30directory20optionsWordpressFollowSymlinks
β”œβ”€β”€ 30directory25filesWordpressWPconfig
β”œβ”€β”€ 30directory25WordpressRewriteIndexPHP
└── 50directoryWordpressWPInstallLocalhost

To activate them, do:

myDomain=domainX;
for myProp in ForceSslStatus WordpressFollowSymlinks WordpressRewriteIndexPHP WordpressWPConfigLocalhost WordpressWPInstallLocalhost; do
	db vhosts setprop $myDomain $myProp enabled;
done

The database looks like this (shortend a little bit):

# db vhosts show domainX
avvp.de=vhost
  Access=public
  ForceSslStatus=enabled
  FtpStatus=disabled
  Indexes=disabled
  PhpVersion=php56
  SslCertificate=/etc/letsencrypt/live/domainX/cert.pem
  WordpressFollowSymlinks=enabled
  WordpressRewriteIndexPHP=enabled
  WordpressWPConfigLocalhost=enabled
  WordpressWPInstallLocalhost=enabled

Lets create the e-smith files in /etc/e-smith/templates-custom/httpd/vhost-extra.

I overwrote ssl-redirect, so it will redirect from http to https and www to non-www as well server-wide.

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]

The e-smith file:

    /etc/e-smith/templates-custom/httpd/vhost-extra20forcessl_redirect

    #
    # 20forcessl_redirect and www { $ForceSslStatus }
    #
{
    $OUT = '';

    if( $ForceSslStatus eq 'enabled') {
	$OUT .= <<REDIRECT;
    RewriteEngine On
    RewriteCond %{HTTPS} off [OR]
    RewriteCond %{HTTP_HOST} ^www\\. [NC]
    RewriteCond %{HTTP_HOST} ^(\?:www\\.)\?(.+)\$ [NC]
    RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R\=301]
REDIRECT
    } else {
	$OUT = '';
    }
}

This next will include and correct the β€œOptions” in virtualhost.conf after the default ones:

#30directory20WordpressOptionsFollowSymlinks
Options -Indexes +FollowSymLinks -Includes

The e-smith file:

/etc/e-smith/templates-custom/httpd/vhost-extra/30directory20optionsFollowSymlinks

{

    use esmith::ConfigDB;
    my $vdb = esmith::ConfigDB->open_ro('vhosts') || die("Can't open vhosts db");
    my $WordpressFollowSymlinks = $vdb->get_prop("$VhostName",'WordpressFollowSymlinks') || 'disabled';

    $OUT = '';

    if ($WordpressFollowSymlinks eq 'enabled') {
           $OUT .= <<FOLLOWSYMWP;
      #30directory20WordpressOptionsFollowSymlinks
      Options -Indexes +FollowSymLinks -Includes
FOLLOWSYMWP
    } else {
       $OUT = '';
    }
}

The next will do a rewrite for the index.php. Needed by wordpress! Normally this is part of the .htaccess in the wordpress root (vhost root). So I can delete the .htaccess file.

  # 30directory25rewriteIndexPHP
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.php$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.php [L]

The e-smith file:

/etc/e-smith/templates-custom/httpd/vhost-extra/30directory25WordpressRewriteIndexPHP

{
    use esmith::ConfigDB;
    my $vdb = esmith::ConfigDB->open_ro('vhosts') || die("Can't open vhosts db");
    my $WordpressRewriteIndexPHP = $vdb->get_prop("$VhostName",'WordpressRewriteIndexPHP') || 'disabled';
    
    $OUT = '';

    if ($WordpressRewriteIndexPHP eq 'enabled') {
        $OUT .= <<REWRITE;
      # 30directory25rewriteIndexPHP
      RewriteEngine On
      RewriteBase /
      RewriteRule ^index\\.php\$ - [L]
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule . /index.php [L]
REWRITE
    } else { 
    $OUT = '';
    }
}

The next will secure the wp-config.php within the vhosts root:

# 30directory22filesWordpressWPconfig
<Files wp-config.php>
   Require ip 127.0.0.1
</Files>

The e-smith file:

/etc/e-smith/templates-custom/httpd/vhost-extra/30directory22filesWordpressWPconfig
{
    use esmith::ConfigDB;
    my $vdb = esmith::ConfigDB->open_ro('vhosts') || die("Can't open vhosts db");
    my $WordpressWPConfigLocalhost = $vdb->get_prop("$VhostName",'WordpressWPConfigLocalhost') || 'disabled';
    
    $OUT = '';

    if ($WordpressWPConfigLocalhost eq 'enabled') {
        $OUT .= <<WPCONFIG;
     # 30directory22filesWordpressWPconfig
     <Files wp-config.php>
        Require ip 127.0.0.1
     </Files>
WPCONFIG
    } else { 
    $OUT = '';
    }
}

As well a the /domainX/wp-config.php, the wp-install.php (initial installation) will be secured:

# 50directoryWordpressWPInstallLocalhost
<Directory /var/lib/nethserver/vhost/domainX/wp-admin>
    <Files wp-install.php>
         Require ip 127.0.0.1
    </Files>
</Directory>

The e-smith file:

/etc/e-smith/templates-custom/httpd/vhost-extra/50directoryWordpressWPInstallLocalhost
{
    use esmith::ConfigDB;
    my $vdb = esmith::ConfigDB->open_ro('vhosts') || die("Can't open vhosts db");
    my $WordpressWPInstallLocalhost = $vdb->get_prop("$VhostName",'WordpressWPInstallLocalhost') || 'disabled';

    $OUT = '';
    $DOCROOT = "{{$DocumentRoot}}";
    #$DOCROOT =~ s/\}//g;
    #$DOCROOT =~ s/\{//g;
    $DOCROOT =~ tr/\{//d;
    $DOCROOT =~ tr/\}//d;

    if ($WordpressWPInstallLocalhost eq 'enabled') {
        $OUT .= <<WPINSTALL;
# 50directoryWordpressWPInstallLocalhost
<Directory $DOCROOT/wp-admin>
    <Files wp-install.php>
         Require ip 127.0.0.1
    </Files>
</Directory>
WPINSTALL
    } else {
    $OUT = '';
    }
}

Activate configuration
With

expand-template /etc/httpd/conf.d/virtualhosts.conf

you can check for errors.

The command

nethserver-httpd-virtualhosts-update

won’t give you any of those error messages!

Then manually start httpd:

service httpd restart #OR 
nethserver-httpd-update

In future everything should work automagically :wink: I will check everything the next days and if something goes wrong I will update here.

Open questions

I think, after I am not using .htacess at all do not have to make these changes. Am I right?

Epel version of wordpress or tgz version (download from wordpress)

There could be reasons to use epel-version of wordpress. Or you repository. But since it is possible to auto-update wordpress from within including plugins and core, there is no need for this and you always have the most actual version. And if you have more than one wordpress installation it is - in my view - more reliable to backup and move everything to another sytem (in case needed). I am doing this now moving from zentyal to nethserver.

Wordpress autoupdates
Enter into domainX/wp-config.php:

/** Auto Update without FTP */
define( 'WP_AUTO_UPDATE_CORE', true );   
define('FS_METHOD', 'direct');

/** Auto update plugins and themes: see
https://codex.wordpress.org/Must_Use_Plugins */

Thanks in advance for your appreciated help. In the meantime I will search further on.

Cheers and greets from Ludwigshafen, Germany
Axel

1 Like

I use the wordpress version from epel for this module, so updates for the core come from epel (a Centos/Redhat LAB sponsored by redhat to get recent version of softwares). So in short please wait after updates , I bet they are often.

Other manners could be to install manually wordpress inside a virtualhost

EDIT: I read to fast, you installed it manually

for what I saw, apache is not able to write, only ftp can do it, so since you do not want FTP, maybe you could inverse the permission

some interrogation with the sticky bit and apache, maybe you could start by allowing the full apache permission to wp-content and wp-admin, then restrict after.

I wonder that if apache is not able to install/write someting in its directories, updates cannot be done.

Hi Axel_Pospischil,

In NethServer web interface, disable FTP. WordPress has its own FTP process.

Change owner:group - if owner is ftp, it will ask for password when updating WordPress core

 chown -R apache:apache /var/lib/nethserver/vhost/domainX

Optional so user β€œother” has no right at all:

 chmod -R o-rwx /var/lib/nethserver/vhost/domainX

Do nothing in /etc/httpd/conf.d/virtualhosts.conf.

After that, update WordPress’s core should work correctly.

ALSO:
In /etc/httpd/conf/httpd.conf so apache will read .htaccess:

 <Directory "/var/www/html">
 ...
  ##### AllowOverride None
 AllowOverride All
 ...
 </Directory>

Restart httpd

 # systemctl restart httpd

For Let’s Encrypt: (must be in /var/www/html/)

 cat > /etc/httpd/conf.d/z_well-known.conf <<'EOT'
 Alias "/.well-known/acme-challenge/" "/var/www/html/.well-known/acme-challenge/"
 <Directory "/var/www/html/.well-known/acme-challenge/">
 Require all granted
 Options -Indexes +FollowSymLinks
 AllowOverride All
 </Directory>
 
 EOT

For domainX

 cat >> /var/lib/nethserver/vhost/domainX/.htaccess <<'EOT'
 # **************************************
 # For permalinks
 <IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 RewriteRule ^index\.php$ - [L]
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule . /index.php [L]
 </IfModule>
  
 # **************************************
 # DIRECTIVES FOR APACHE
 Options +FollowSymLinks
 Options -Indexes
 
 # **************************************
 # Protect wp-config
 <Files wp-config.php>
  order allow,deny
  deny from all
 </Files>
 
 #**************************************
 # Protect htaccess itself
 <Files .htaccess>
 order allow,deny
 deny from all
 </Files>
 
 EOT

For potential problem - WordPress cannot find…

 cat >> /var/lib/nethserver/vhost/domainX/wp-config.php <<'EOT'

 ###############################################
 # Ref: https://juliencrego.com/wordpress-impossible-de-localiser-le-repertoire-de-contenu/
 #
 if(is_admin()){
     add_filter('filesystem_method', create_function('$a', 'return "direct";' ));    
     define( 'FS_CHMOD_DIR', 0751 );
 }
 ###############################################
 
 EOT

Michel-AndrΓ©

1 Like

Thank you all for the answers. I am positively surprised. Especially because it helped at once.

Thank you very much. I will post my solution and update the first post for others with the same problem to get things done :wink:

Cheers Axel

1 Like

Welcome in the nethserver community, we aim to provide helps if obviously we know the answer :slight_smile:

I am lazzy, epel is enabled per default in NS, so I do nothing to set the rpm to the current version. Actually the version in epel is 5.1.1-4.el7, the last is 5.2, but I don’t think you have a lot of new features. I think the matter to install manually is probably better and could be the most valuable way, but some people asked for this rpm, when I stated I won’t do a ns7 version, so I have a market share :slight_smile:

As ever I did it because I can do it and it is fun.