Archive for the ‘Web and CMS’ Category

Create and Configure SSL bundle file for GoGetSSL issued certificate in Apache Webserver on Linux

Saturday, November 3rd, 2018

gogetssl-install-certificate-on-linux-howto-sslcertificatechainfile-obsolete

I had a small task to configure a new WildCard SSL for domains on a Debian GNU / Linux Jessie running Apache 2.4.25.

The official documentation on how to install the SSL certificate on Linux given by GoGetSSL (which is by COMODO was obsolete as of time of writting this article and suggested as install instructions:
 

SSLEngine on
SSLCertificateKeyFile /etc/ssl/ssl.key/server.key
SSLCertificateFile /etc/ssl/ssl.crt/yourDomainName.crt
SSLCertificateChainFile /etc/ssl/ssl.crt/yourDomainName.ca-bundle


Adding such configuration to domain Vhost and testing with apache2ctl spits an error like:

 

root@webserver:~# apache2ctl configtest
AH02559: The SSLCertificateChainFile directive (/etc/apache2/sites-enabled/the-domain-name-ssl.conf:17) is deprecated, SSLCertificateFile should be used instead
Syntax OK

 


To make issued GoGetSSL work with Debian Linux, hence, here is the few things done:

The files issued by Gogetssl.COM were the following:

 

AddTrust_External_CA_Root.crt
COMODO_RSA_Certification_Authority.crt
the-domain-name.crt


The webserver had already SSL support via mod_ssl Apache module, e.g.:

 

root@webserver:~# ls -al /etc/apache2/mods-available/*ssl*
-rw-r–r– 1 root root 3112 окт 21  2017 /etc/apache2/mods-available/ssl.conf
-rw-r–r– 1 root root   97 сеп 19  2017 /etc/apache2/mods-available/ssl.load
root@webserver:~# ls -al /etc/apache2/mods-enabled/*ssl*
lrwxrwxrwx 1 root root 26 окт 19  2017 /etc/apache2/mods-enabled/ssl.conf -> ../mods-available/ssl.conf
lrwxrwxrwx 1 root root 26 окт 19  2017 /etc/apache2/mods-enabled/ssl.load -> ../mods-available/ssl.load


For those who doesn't have mod_ssl enabled, to enable it quickly run:

 

# a2enmod ssl


The VirtualHost used for the domains had Apache config as below:

 

 

 

NameVirtualHost *:443

<VirtualHost *:443>
    ServerAdmin support@the-domain-name.com
    ServerName the-domain-name.com
    ServerAlias *.the-domain-name.com the-domain-name.com

    DocumentRoot /home/the-domain-namecom/www
    SSLEngine On
#    <Directory />
#        Options FollowSymLinks
#        AllowOverride None
#    </Directory>
    <Directory /home/the-domain-namecom/www>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride None
        Include /home/the-domain-namecom/www/htaccess_new.txt
        Order allow,deny
        allow from all
    </Directory>

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined

#    Alias /doc/ "/usr/share/doc/"
#   <Directory "/usr/share/doc/">
#       Options Indexes MultiViews FollowSymLinks
#       AllowOverride None
#       Order deny,allow
#       Deny from all
#       Allow from 127.0.0.0/255.0.0.0 ::1/128
#   </Directory>
SSLCertificateKeyFile /etc/apache2/ssl/the-domain-name.com.key
SSLCertificateFile /etc/apache2/ssl/chain.crt

 

</VirtualHost>

The config directives enabling and making the SSL actually work are:
 

SSLEngine On
SSLCertificateKeyFile /etc/apache2/ssl/the-domain-name.com.key
SSLCertificateFile /etc/apache2/ssl/chain.crt

 

The chain.crt file is actually a bundle file containing a bundle of the gogetssl CA_ROOT and RSA_Certification_Authority 3 files, to prepare that file, I've used bundle.sh small script found on serverfault.com here I've made a mirror of bundle.sh on pc-freak.net here   the script content is as follows:

To prepare the chain.crt  bundle, I ran:

 

sh create-ssl-bundle.sh _iq-test_cc.crt chain.crt
sh create-ssl-bundle.sh _iq-test_cc.crt >chain.crt
sh create-ssl-bundle.sh COMODO_RSA_Certification_Authority.crt >> chain.crt
sh create-ssl-bundle.sh bundle.sh AddTrust_External_CA_Root.crt >> chain.crt


Then I copied the file to /etc/apache2/ssl together with the-domain-name.com.key file earlier generated using openssl command earlier explained in my article how to install RapidSSL certificate on Linux

/etc/apache2/ssl was not previously existing (on Debian Linux), so to create it:

 

root@webserver:~# mkdir /etc/apache2/ssl
root@webserver:~# ls -al /etc/apache2/ssl/chain.crt
-rw-r–r– 1 root root 20641 Nov  2 12:27 /etc/apache2/ssl/chain.crt
root@webserver:~# ls -al /etc/apache2/ssl/the-domain-name.com.key
-rw-r–r– 1 root root 6352 Nov  2 20:35 /etc/apache2/ssl/the-domain-name.com.key

 

As I needed to add the SSL HTTPS configuration for multiple domains, further on I've wrote and used a tiny shell script add_new_vhost.sh which accepts as argument the domain name I want to add. The script works with a sample Skele (Template) file, which is included in the script itself and can be easily modified for the desired vhost config.
To add my multiple domains, I've used the script as follows:
 

sh add_new_vhost.sh add-new-site-domain.com
sh add_new_vhost.sh add-new-site-domain1.com


etc.

Here is the complete script as well:

 

#!/bin/sh
# Shell script to add easily new domains for virtual hosting on Debian machines
# arg1 should be a domain name
# This script takes the domain name which you type as arg1 uses it and creates
# Docroot / cgi-bin directory for the domain, create seperate site's apache log directory
# then takes a skele.com file and substitutes a skele.com with your domain name and directories
# This script's aim is to easily enable sysadmin to add new domains in Debian
sites_base_dir=/var/www/jail/home/www-data/sites/;
# the directory where the skele.com file is
skele_dir=/etc/apache2/sites-available;
# base directory where site log dir to be created
cr_sep_log_file_d=/var/log/apache2/sites;
# owner of the directories
username='www-data';
# read arg0 and arg1
arg0=$0;
arg1=$1;
if [[ -z $arg1 ]]; then
echo "Missing domain name";
exit 1;
fi

 

# skele template
echo "#
#  Example.com (/etc/apache2/sites-available/www.skele.com)
#
<VirtualHost *>
        ServerAdmin admin@design.bg
        ServerName  skele.com
        ServerAlias www.skele.com


        # Indexes + Directory Root.
        DirectoryIndex index.php index.htm index.html index.pl index.cgi index.phtml index.jsp index.py index.asp

        DocumentRoot /var/www/jail/home/www-data/sites/skelecom/www/docs
        ScriptAlias /cgi-bin "/var/www/jail/home/www-data/sites/skelecom/cgi-bin"
        
        # Logfiles
        ErrorLog  /var/log/apache2/sites/skelecom/error.log
        CustomLog /var/log/apache2/sites/skelecom/access.log combined
#       CustomLog /dev/null combined
      <Directory /var/www/jail/home/www-data/sites/skelecom/www/docs/>
                Options FollowSymLinks MultiViews -Includes
                AllowOverride None
                Order allow,deny
                allow from all
                # This directive allows us to have apache2's default start page
                # in /apache2-default/, but still have / go to the right place
#               RedirectMatch ^/$ /apache2-default/
        </Directory>

        <Directory /var/www/jail/home/www-data/sites/skelecom/www/docs/>
                Options FollowSymLinks ExecCGI -Includes
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

</VirtualHost>
" > $skele_dir/skele.com;

domain_dir=$(echo $arg1 | sed -e 's/\.//g');
new_site_dir=$sites_base_dir/$domain_dir/www/docs;
echo "Creating $new_site_dir";
mkdir -p $new_site_dir;
mkdir -p $sites_base_dir/cgi-bin;
echo "Creating sites's Docroot and CGI directory";
chown -R $username:$username $new_site_dir;
chown -R $username:$username $sites_base_dir/cgi-bin;
echo "Creating site's Log files Directory";
mkdir -p $cr_sep_log_file_d/$domain_dir;
echo "Creating sites's VirtualHost file and adding it for startup";
sed -e "s#skele.com#$arg1#g" -e "s#skelecom#$domain_dir#g" $skele_dir/skele.com >> $skele_dir/$arg1;
ln -sf $skele_dir/$arg1 /etc/apache2/sites-enabled/;
echo "All Completed please restart apache /etc/init.d/apache restart to Load the new virtual domain";

# Date Fri Jan 11 16:27:38 EET 2008


Using the script saves a lot of time to manually, copy vhost file and then edit it to change ServerName directive, for vhosts whose configuration is identical and only the ServerName listener has to change, it is perfect to create all necessery domains, I've created a simple text file with each of the domains and run it in a loop:
 

while :; do sh add_new_vhost.sh $i; done < domain_list.txt
 

 

Display Content of SSL certificate .pem file with openssl command

Thursday, October 11th, 2018

display-content-of-pem-der-and-scr-file-how-to-view-pem-file-linux

If you have generated a .pem formatted SSL certificate or you have multiple .pem SSL certificates and you're not sure which .pem file is generated for which domain / subdomain it is useful to Display content of SSL Certificate .PEM file with openssl command.

Viewing certificate's content is also very useful if you have hosted multiple websites hosted on a server and you want to check which of the SSLs assigned in the Virtualhosts has Expired (for example if you have domains that expire in short term period (365 days).


1. How to Display Content of SSL certificate .pem file?

 

root@pcfreak:~# openssl x509 -in cert.pem -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            04:d1:ad:55:91:f3:f9:ef:3e:53:ea:2c:3a:f4:5f:e6:ce:c1
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
        Validity
            Not Before: Oct 10 17:49:34 2018 GMT
            Not After : Jan  8 17:49:34 2019 GMT
        Subject: CN = mail.pc-freak.net

        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:bb:b0:c9:1c:83:82:61:47:f9:c2:73:60:c0:48:
                    e6:0c:f2:a1:ff:db:ae:f1:84:17:14:5d:fc:a3:b2:
                    e4:00:3a:d1:85:42:90:da:41:a9:e9:a8:af:20:3d:
                    12:ef:8e:ca:61:a1:71:f2:cc:43:bf:40:0d:fa:08:
                    7d:d9:61:2b:ea:5d:30:e0:52:43:db:18:30:92:0c:
                    2c:ce:87:93:84:ea:91:61:b7:70:db:11:7c:b6:a4:
                    33:de:d8:3f:d6:61:47:42:f2:36:12:7f:3d:e3:f7:
                    5b:11:3e:1c:f0:af:96:cd:61:8a:1a:a0:f0:b5:23:
                    65:73:b6:b4:9c:19:a7:09:dd:43:96:37:ac:48:fc:
                    21:07:02:52:67:26:2c:81:24:f4:d7:10:e6:f4:12:
                    69:53:ef:91:2a:15:6a:21:06:22:ea:fe:31:38:82:
                    b4:5a:b5:9b:67:90:16:b8:31:e8:27:38:f2:41:b9:
                    19:02:8f:c7:6e:e1:2c:84:75:19:6d:bb:30:3b:d2:
                    02:f0:65:f1:76:82:15:9c:ce:31:3a:d4:7c:83:ca:
                    d1:f9:e1:b7:76:f6:78:93:47:d2:00:f9:63:aa:94:
                    41:d4:78:d0:ee:bc:e6:e9:14:14:e4:ae:54:31:88:
                    f8:58:8d:7b:3e:9f:87:5c:f2:04:e5:07:e0:4c:9a:
                    81:eb
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                DB:AB:81:E3:14:5F:6D:BE:B4:78:7B:5E:7D:FB:66:BF:56:37:C5:1D
            X509v3 Authority Key Identifier:
                keyid:A8:4A:6A:63:04:7D:DD:BA:E6:D1:39:B7:A6:45:65:EF:F3:A8:EC:A1

 

            Authority Information Access:
                OCSP – URI:http://ocsp.int-x3.letsencrypt.org
                CA Issuers – URI:http://cert.int-x3.letsencrypt.org/

            X509v3 Subject Alternative Name:
                DNS:mail.pc-freak.net
            X509v3 Certificate Policies:
                Policy: 2.23.140.1.2.1
                Policy: 1.3.6.1.4.1.44947.1.1.1
                  CPS: http://cps.letsencrypt.org
                  User Notice:
                    Explicit Text: This Certificate may only be relied upon by Relying Parties and only in accordance with the Certificate Policy found at https://letsencrypt.org/repository/

            CT Precertificate SCTs:
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : E2:69:4B:AE:26:E8:E9:40:09:E8:86:1B:B6:3B:83:D4:
                                3E:E7:FE:74:88:FB:A4:8F:28:93:01:9D:DD:F1:DB:FE
                    Timestamp : Oct 10 18:49:34.453 2018 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:46:02:21:00:D6:DE:47:AD:D2:32:BE:BE:DD:B3:EB:
                                EE:84:9E:02:8A:4F:33:E2:63:21:D5:F7:4D:47:82:92:
                                AB:B9:0A:49:62:02:21:00:E8:7D:17:81:32:E3:4F:CF:
                                2D:79:8C:97:46:E1:EF:5E:99:F4:8A:8B:B5:6D:23:5F:
                                05:84:E2:14:6A:56:8E:A0
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : 29:3C:51:96:54:C8:39:65:BA:AA:50:FC:58:07:D4:B7:
                                6F:BF:58:7A:29:72:DC:A4:C3:0C:F4:E5:45:47:F4:78
                    Timestamp : Oct 10 18:49:34.451 2018 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:44:02:20:6C:8E:E7:E2:70:AD:33:A6:5C:E0:89:84:
                                FB:0B:F6:E1:5C:05:06:0A:A8:DB:8B:1C:7A:D0:52:99:
                                5F:3F:A2:64:02:20:4B:CD:0B:E7:A0:27:04:31:19:18:
                                58:99:51:73:49:6B:77:25:A7:E7:5B:10:8C:BD:ED:54:
                                03:DD:40:E4:2D:31
    Signature Algorithm: sha256WithRSAEncryption
         9c:86:b3:34:64:af:ac:9d:c4:d3:a7:cc:fc:8a:32:18:75:95:
         95:47:9b:9c:3c:0e:3b:61:f9:88:61:38:1a:a6:92:69:3d:14:
         6a:53:13:14:65:e6:ca:fa:b9:8e:48:c9:d4:73:f6:e4:74:8a:
         1f:2b:f2:14:86:f1:18:55:26:1b:a0:97:89:15:0b:62:c6:2b:
         27:81:6f:60:af:55:68:b3:2c:5b:10:56:a2:7d:28:cb:8e:fc:
         f0:21:65:78:9b:3a:52:d3:9d:27:ff:d7:24:95:de:0f:d8:3d:
         a2:43:6e:fc:a5:2d:f2:ad:37:e9:ea:db:b5:75:b8:7c:ad:23:
         45:1d:bd:fe:4e:36:c7:f4:e2:3d:47:c9:06:fc:cb:75:ba:d4:
         0a:90:17:ea:e1:7f:49:e6:68:27:97:8a:70:c7:50:e9:19:4a:
         8a:21:18:26:79:a3:61:ff:1b:26:9e:fe:85:8f:20:ed:c6:4d:
         c1:0e:04:21:a8:05:d4:29:69:99:53:63:81:c7:d5:58:71:df:
         02:b5:94:c9:36:48:c9:35:80:ab:71:78:d9:12:f6:f5:10:25:
         3d:38:c5:40:75:25:b1:95:18:d8:1c:96:f1:c6:1a:d2:c4:99:
         f5:01:2e:f4:e1:4a:1f:10:42:0e:34:ed:92:8e:53:9f:c2:7b:
         11:51:78:6a
—–BEGIN CERTIFICATE—–
MIIGDTCCBPWgAwIBAgISBNGtVZHz+e8+U+osOvRf5s7BMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xODEwMTAxNzQ5MzRaFw0x
OTAxMDgxNzQ5MzRaMBwxGjAYBgNVBAMTEW1haWwucGMtZnJlYWsubmV0MIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu7DJHIOCYUf5wnNgwEjmDPKh/9uu
8YQXFF38o7LkADrRhUKQ2kGp6aivID0S747KYaFx8sxDv0AN+gh92WEr6l0w4FJD
2xgwkgwszoeThOqRYbdw2xF8tqQz3tg/1mFHQvI2En894/dbET4c8K+WzWGKGqDw
tSNlc7a0nBmnCd1DljesSPwhBwJSZyYsgST01xDm9BJpU++RKhVqIQYi6v4xOIK0
WrWbZ5AWuDHoJzjyQbkZAo/HbuEshHUZbbswO9IC8GXxdoIVnM4xOtR8g8rR+eG3
dvZ4k0fSAPljqpRB1HjQ7rzm6RQU5K5UMYj4WI17Pp+HXPIE5QfgTJqB6wIDAQAB
o4IDGTCCAxUwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
BgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTbq4HjFF9tvrR4e159+2a/
VjfFHTAfBgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBvBggrBgEFBQcB
AQRjMGEwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmludC14My5sZXRzZW5jcnlw
dC5vcmcwLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5jcnlw
dC5vcmcvMBwGA1UdEQQVMBOCEW1haWwucGMtZnJlYWsubmV0MIH+BgNVHSAEgfYw
gfMwCAYGZ4EMAQIBMIHmBgsrBgEEAYLfEwEBATCB1jAmBggrBgEFBQcCARYaaHR0
cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwgasGCCsGAQUFBwICMIGeDIGbVGhpcyBD
ZXJ0aWZpY2F0ZSBtYXkgb25seSBiZSByZWxpZWQgdXBvbiBieSBSZWx5aW5nIFBh
cnRpZXMgYW5kIG9ubHkgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBDZXJ0aWZpY2F0
ZSBQb2xpY3kgZm91bmQgYXQgaHR0cHM6Ly9sZXRzZW5jcnlwdC5vcmcvcmVwb3Np
dG9yeS8wggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdwDiaUuuJujpQAnohhu2O4PU
Puf+dIj7pI8okwGd3fHb/gAAAWZfUA/1AAAEAwBIMEYCIQDW3ket0jK+vt2z6+6E
ngKKTzPiYyHV901HgpKruQpJYgIhAOh9F4Ey40/PLXmMl0bh716Z9IqLtW0jXwWE
4hRqVo6gAHUAKTxRllTIOWW6qlD8WAfUt2+/WHopctykwwz05UVH9HgAAAFmX1AP
8wAABAMARjBEAiBsjuficK0zplzgiYT7C/bhXAUGCqjbixx60FKZXz+iZAIgS80L
56AnBDEZGFiZUXNJa3clp+dbEIy97VQD3UDkLTEwDQYJKoZIhvcNAQELBQADggEB
AJyGszRkr6ydxNOnzPyKMhh1lZVHm5w8Djth+YhhOBqmkmk9FGpTExRl5sr6uY5I
ydRz9uR0ih8r8hSG8RhVJhugl4kVC2LGKyeBb2CvVWizLFsQVqJ9KMuO/PAhZXib
OlLTnSf/1ySV3g/YPaJDbvylLfKtN+nq27V1uHytI0Udvf5ONsf04j1HyQb8y3W6
1AqQF+rhf0nmaCeXinDHUOkZSoohGCZ5o2H/Gyae/oWPIO3GTcEOBCGoBdQpaZlT
Y4HH1Vhx3wK1lMk2SMk1gKtxeNkS9vUQJT04xUB1JbGVGNgclvHGGtLEmfUBLvTh
Sh8QQg407ZKOU5/CexFReGo=
—–END CERTIFICATE—–

 

Same way a .der files content / encryption algorithm and domain name could be grasped.
 

root@pcfreak:~# openssl x509 -in cert.der -inform der -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            ad:c2:96:6f:4b:db:31:5c
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = example.com
        Validity
            Not Before: Jun 22 04:00:37 2015 GMT
            Not After : Jul 22 04:00:37 2015 GMT

        Subject: CN = example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (512 bit)

                Modulus:
                    00:ac:75:73:b4:51:ed:1f:dd:ae:70:52:43:fc:df:
                    c7:5b:d0:2c:75:1b:14:b8:75:01:04:10:e5:1f:03:
                    65:45:dd:df:a7:9f:34:ae:fd:be:e9:05:84:df:47:
                    16:81:d9:89:4b:ce:8e:6d:1c:fa:95:44:e8:af:84:
                    74:4f:ed:c2:e5
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                26:CF:C8:ED:4B:D7:94:B2:E4:25:03:58:24:8F:04:C0:74:D5:97:8A
            X509v3 Authority Key Identifier:
                keyid:26:CF:C8:ED:4B:D7:94:B2:E4:25:03:58:24:8F:04:C0:74:D5:97:8A

 

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
         0c:8b:ff:12:80:9e:4c:90:bc:26:b0:96:20:ab:76:0c:64:71:
         d2:15:48:a5:33:f6:47:e4:03:df:76:5e:0f:cd:e1:1b:5e:d1:
         4d:c2:1f:8d:b8:63:2f:c9:7d:6e:5c:3b:cb:cd:a3:d0:d8:27:
         74:66:a3:76:06:a5:fb:81:3a:b6
—–BEGIN CERTIFICATE—–
MIIBdTCCAR+gAwIBAgIJAK3Clm9L2zFcMA0GCSqGSIb3DQEBCwUAMBYxFDASBgNV
BAMMC2V4YW1wbGUuY29tMB4XDTE1MDYyMjA0MDAzN1oXDTE1MDcyMjA0MDAzN1ow
FjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA
rHVztFHtH92ucFJD/N/HW9AsdRsUuHUBBBDlHwNlRd3fp580rv2+6QWE30cWgdmJ
S86ObRz6lUTor4R0T+3C5QIDAQABo1AwTjAdBgNVHQ4EFgQUJs/I7UvXlLLkJQNY
JI8EwHTVl4owHwYDVR0jBBgwFoAUJs/I7UvXlLLkJQNYJI8EwHTVl4owDAYDVR0T
BAUwAwEB/zANBgkqhkiG9w0BAQsFAANBAAyL/xKAnkyQvCawliCrdgxkcdIVSKUz
9kfkA992Xg/N4Rte0U3CH424Yy/JfW5cO8vNo9DYJ3Rmo3YGpfuBOrY=
—–END CERTIFICATE—–

 

2. How to display content and info about .CSR (Certificate Signing request)

 

root@pcfreak:~# openssl req -in cert.csr -noout -text
 

Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = BG, ST = BG, L = Dobrich, O = Pc Freak, CN = mail.pc-freak.net, emailAddress = hipo@pc-freak.net
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:b1:83:a7:07:62:19:d4:60:95:58:49:de:b3:48:
                    a8:39:31:fa:5a:bd:2b:d6:73:94:50:36:72:74:18:
                    58:b6:27:d3:0b:26:75:15:a8:ba:1b:77:a7:c9:54:
                    96:1f:c7:8d:da:bd:c9:17:91:53:85:9e:0a:f4:71:
                    3c:fb:d6:e4:75:41:c1:95:32:e1:22:fc:7b:1f:36:
                    23:12:00:ca:37:27:d5:f9:9b:29:48:4a:51:95:d1:
                    40:d0:ea:94:51:98:98:6b:d3:d9:79:1d:a1:65:bb:
                    a9:d1:ab:c9:46:6e:03:ee:24:45:e5:f2:73:e5:f4:
                    82:4a:08:57:b1:06:52:c3:cc:42:9a:02:5b:7a:7c:
                    bd:34:d5:5f:d7:ba:ef:27:d5:3d:97:16:69:06:c7:
                    c1:06:5e:d9:07:16:3f:a3:61:50:9d:dd:ea:95:32:
                    f1:ee:93:82:48:df:20:8b:ae:d2:95:89:05:e4:3d:
                    0c:d7:e1:cf:07:ae:55:84:11:06:92:be:34:b4:a2:
                    a1:ce:07:06:bf:21:bc:80:e2:03:d2:85:b4:64:02:
                    8d:cd:d2:86:1c:49:41:52:43:a8:12:f8:ef:2c:f4:
                    be:a0:dc:ac:ea:27:3a:f9:ab:ab:27:da:28:63:1d:
                    10:5a:4f:b8:51:42:40:ae:be:c0:2d:e9:a3:5a:5a:
                    23:7f
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
         47:f0:54:cd:5e:46:6f:2c:cc:48:7e:85:f0:a8:96:10:ca:a3:
         15:98:77:d3:02:95:8c:67:84:e3:55:d2:0c:e8:d5:a7:ba:82:
         95:fb:ce:73:4c:bc:8f:da:85:97:0c:a8:59:32:b3:a4:af:0a:
         80:4c:78:7f:62:cd:1b:00:01:e8:51:27:9c:eb:75:29:80:e9:
         99:24:fc:86:e2:09:28:be:47:5a:1d:bf:b1:b4:c4:29:4e:6e:
         f3:70:b4:58:f8:d9:a6:63:03:8b:a1:ef:ee:6d:1a:35:33:1e:
         b2:32:25:c1:33:37:3d:46:82:37:9b:0d:4c:40:20:ae:ff:e0:
         cc:51:a2:6b:dd:74:26:d6:93:26:89:c7:76:29:13:cf:6e:5a:
         0f:7c:1b:f5:80:be:3b:6a:a3:c0:10:cd:07:1e:a2:31:8b:49:
         94:d7:63:cf:93:8d:80:03:75:4a:76:b4:cd:14:fe:96:62:61:
         6b:96:8f:c0:a5:ef:67:c7:5e:c0:a5:4b:4f:95:57:b6:43:03:
         8b:6d:10:5f:ab:f2:95:54:ba:85:8e:8b:c1:99:ea:fd:3f:5e:
         23:01:d4:27:f3:e9:20:37:c4:05:47:30:67:94:53:f0:87:27:
         48:73:57:55:f2:70:04:b1:e9:29:eb:2e:2c:9a:cc:55:f4:cc:
         a4:71:c2:5a


That's all folks 🙂

 

Run multiple PHP versions (PHP 5 and PHP 7) with NGINX on the same server howto

Wednesday, October 3rd, 2018

how-to-run-multiple-php-versions-on-same-Linux-server-nginx-webserver-php5-7-logo

It is common sysadmin task to have two versions of PHP running on the same physical or Virtual server to be able to run simultaneously old PHP 5.X legacy applications and PHP 7.X written websites / web applications.

In the past this task was much more complicated than today  you had to compile for example Apache and PHP modules from source and enable it through fastcgi.
Today with the raise of NGINX Web Server and its possibility to run much of the PHP Apps running on top of Apache.
For the sake of this tutorial I'll be using Debian Strecth 9.0.
The reason to use NGINX instead of Apache for this tutorial are numerous, it is light weight (uses less resources – CPU ./ Memory) it is secure smaller in size.
 

1. Install NGINX Web Server

 

# apt-get install –yes nginx 

 

2. Install PHP.7.0 FPM module

 

# apt-get install php7.0-cli php7.0-fpm
 

 

3. Install PHP 5.6 FPM Using external deb repository

Debian default repositories does not include support for PHP 5.6, hence we need to add the respective repositories providing PHP 5.6

 

# apt-get install apt-transport-https

 

# curl https://packages.sury.org/php/apt.gpg | apt-key add –
echo 'deb https://packages.sury.org/php/ stretch main' > /etc/apt/sources.list.d/deb.sury.org.list
apt-get update

 

Next install PHP 5.6 from just added repos

 

# apt-get install –yes php5.6-cli php5.6-fpm

 

4. Check Multiple PHP versions PHP 5 and PHP 7 aree properly installed 

 

# php7.0 -v
PHP 7.0.15-1 (cli)
# php5.6 -v

 

Debian has a default set-up for PHP CLI (Console Interface command) pointing to PHP 7.0, e.g.

 

# php -v
PHP 7.0.15-1 (cli)

 

If you prefer to use as prefer PHP 5.6 instead you can do it with debian update-alternative cmd:

 

# update-alternatives –config php

 

5. Configure both installed PHP -es

Edit /etc/php/7.0/fpm/pool.d/www.conf and look for the listen option. It should equal to /run/php/php7.0-fpm.sock or something alike.
Now do the same for 5.6, it should contain the same with just 5.6 instead of 7.0. Note that it could also be a bind address, i.e. IP address with port (which is performance-wise more suitable for production than sockets). 

 

6. Configuring NGINX webserver


Nginx configuration files are stored in /etc/nginx 

– On Debian the .deb package structure of nginx is is made that all available virtual hosts for nginx just like for Apache are stored  in sites-available directory and production enabled virtualhosts are symlinks to sites-enabled

– Shared configuration for reuse among multiple domains is stored in inside the snippets directory

– fastcgi.conf file contains FastCGI specific variables that are passed to PHP

– The snippets/fastcgi-php.conf is just a helper file to prepare configuration that is passed to PHP module

It is a good idea to remove any unnecessery configuration from /etc/nginx/sites-enabled 
 

7. Create configuration for PHP 7.0


To make simple the test the main (root) directory of nginx will be set to have a simple phpinfo(); file.
 

mkdir /var/www/site-with-php7
echo -e '<?php\nphpinfo();' > /var/www/site-with-php7/index.php 


Then create actual Nginx configuration

 

# vim /etc/nginx/sites-available/site-with-enabed-php7.X

 

server {
    listen 8770 default_server;
    listen [::]:8870 default_server;

    server_name _;
    root /var/www/site-with-php7;
    index index.php;
    location / {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock; # adjust for the listen setting discussed above
    }


As seen from configuration PHP 7 will be serving PHP scripts written for php 7  on TCP port 8870

 

8. Create configuration for PHP 5.6

 

# mkdir /var/www/site-with-php5.6
# echo -e '<?php\nphpinfo();' > /var/www/site-with-php5.6/index.php

 

server {
    listen 8756 default_server;
    listen [::]:8856 default_server;

    server_name _;
    root /var/www/site-with-php5.6;
    index index.php;
    location / {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php5.6-fpm.sock; # adjust for the listen setting discussed above
    }
}

As you see from configuration PHP 5.6 will be serving PHP 5.6 files on TCP port 8756

To enable both NGINX configurations to load enable both nginx vhosts as there is no a2ensite like for enabling NGINX configurations the following  cmd does it
 

# ln -s /etc/nginx/sites-available/site-with-php5.6 /etc/nginx/sites-enabled/
#  ln -s /etc/nginx/sites-available/site-with-php7.0 /etc/nginx/sites-enabled/

To load the new NGINX Virtualhost configurations, restart next:
 

# systemctl reload nginx.service

 

9. Testing NGINX + PHP configuration set-up on port 8870 / 8876

 


– Test NGINX connection on 8876
 

lynx -dump http://localhost:8870

– Test NGINX connection on 8870
 

lynx -dump http://localhost:8870

Both commands should dump you output from PHP 7 (if your server lacks lynx i warmly recommend it, though you can use wget to test).

 

To sum it up


Even though generally it is a bad idea to have 2 instances of application service be it NGINX / Apache from security point of view, it is sometimes a necessity especially when you
or your customers are unwilling to invest money for upgrade of their websites / application infrastructure and if the clients want to keep obsolete PHP code and mix it with a new.
Still migration will be required as you would perhaps want to have some kind of Load Balancer round robin with another NGINX / Apache or Haproxy to make different applications
open under a separate CDN hostname
.

How to reset lost OwnCloud admin password credentials with Linux command

Friday, September 28th, 2018

owncloud-change-password-on-owncloud-7-8-linux-howto

Some time ago I've explained how to set-up a personal Cloud via OwnCloud on Linux to be able to access and share your data across all your Phone / Notebook / PCs / Tablet devices and be free from Amazon Cloud slavery.

Now as I haven't used a setup of OwnCloud it seems I forgot my OwnCloud password and besides that I am not sure which email address I filled as a recovery email and was lazy to go through all the OwnCloud MySQL database tables, thus I looked for
other ways to recover the forgotten password. Finally I ended up using the command line, below is how OwnCloud 7 admin password can be easily reset (recovered) with occ php command:

 

root@pcfreak:/var/www/owncloud# sudo -u www-data php occ user:resetpassword admin
PHP module intl not installed.
Please ask your server administrator to install the module.

 

An unhandled exception has been thrown:
Exception: Environment not properly prepared. in /var/www/owncloud/lib/private/Console/Application.php:135
Stack trace:
#0 /var/www/owncloud/console.php(105): OC\Console\Application->loadCommands(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#1 /var/www/owncloud/occ(11): require_once('/var/www/ownclo…')
#2 {main}root@pcfreak:/var/www/owncloud# apt-cache search php|grep -i intl
php-intl – Internationalisation module for PHP [default]
php-symfony-polyfill-intl-grapheme – Symfony polyfill for intl's grapheme_* functions
php-symfony-polyfill-intl-icu – Symfony polyfill for intl's ICU-related data and classes
php-symfony-polyfill-intl-normalizer – Symfony polyfill for intl's Normalizer class and related functions
php7.0-intl – Internationalisation module for PHP
php-symfony-intl – limited replacement layer for the PHP extension intl
php-symfony-locale – deprecated replacement layer for the PHP extension intl
php5-intl – internationalisation module for php5
root@pcfreak:/var/www/owncloud# apt-get install php7.0-intl
Четене на списъците с пакети… Готово
Изграждане на дървото със зависимости       
Четене на информацията за състоянието… Готово
Следните пакети са били инсталирани автоматично и вече не са необходими:
  docutils-common docutils-doc gcj-4.9-jre-lib gnat-4.9-base libasn1-8-heimdal libavcodec56 libavformat56 libavresample2 libavutil54 libbind9-90 libboost-program-options1.55.0 libboost-python1.55.0 libcompress-raw-bzip2-perl libcompress-raw-zlib-perl libcrypt-openssl-random-perl
  libdnet libdns-export100 libdns100 libegl1-mesa-drivers libexiv2-13 libgcj15 libglew1.10 libgnat-4.9 libgnutls-openssl27 libgphoto2-port10 libgphoto2-port10:i386 libhcrypto4-heimdal libhdb9-heimdal libheimbase1-heimdal libhx509-5-heimdal libimobiledevice4 libinput5 libintl-perl
  libintl-xs-perl libirs-export91 libisc-export95 libisc95 libisccc90 libisccfg-export90 libisccfg90 libjson-c3 libkrb5-26-heimdal libllvm3.5:i386 libllvm3.8 liblognorm1 liblwres90 libntdb1 libopenvg1-mesa libplist2 libprocps3 libpsl0 libroken18-heimdal librrd4 libtfm1
  libusbmuxd2 libvpx1:i386 libwebpdemux1 libwebpdemux2 libwebpmux1 libwind0-heimdal libwings2 libwraster3 libwutil3 libx264-142 libxtables10 linux-image-3.16.0-4-amd64 python-characteristic python-docutils python-ndg-httpsclient python-ntdb python-pil python-pygments
  python-pyinotify python-roman python-twisted-lore python-twisted-mail python-twisted-names python-twisted-news python-twisted-runner python-twisted-words
Използвайте „apt autoremove“ за да ги премахнете.
Следните НОВИ пакети ще бъдат инсталирани:
  php7.0-intl
0 актуализирани, 1 нови инсталирани, 0 за премахване и 1 без промяна.
Необходимо е да се изтеглят 124 kB архиви.
След тази операция ще бъде използвано 523 kB допълнително дисково пространство.
Изт:1 http://ftp.uk.debian.org/debian stable/main amd64 php7.0-intl amd64 7.0.30-0+deb9u1 [124 kB]
Изтеглени 124 kB за 1с (93,7 kB/сек)        

 

Selecting previously unselected package php7.0-intl.
(Reading database … 210111 files and directories currently installed.)
Preparing to unpack …/php7.0-intl_7.0.30-0+deb9u1_amd64.deb …
Unpacking php7.0-intl (7.0.30-0+deb9u1) …
Processing triggers for libapache2-mod-php7.0 (7.0.30-0+deb9u1) …
Setting up php7.0-intl (7.0.30-0+deb9u1) …

Creating config file /etc/php/7.0/mods-available/intl.ini with new version
Processing triggers for libapache2-mod-php7.0 (7.0.30-0+deb9u1) …
root@pcfreak:/var/www/owncloud# occ user:resetpassword admin
bash: occ: командата не е открита
root@pcfreak:/var/www/owncloud# sudo -u www-data php occ user:resetpassword admin
Enter a new password: 
Confirm the new password: 
Successfully reset password for admin
root@pcfreak:/var/www/owncloud# 
 

 

 

root@pcfreak:/var/www/owncloud# sudo -u www-data php occ user:resetpassword admin
Enter a new password: 
Confirm the new password: 
Successfully reset password for admin


owncloud-screenshot-on-my-debian-gnu-linux-in-chrome-browser

That's all now I can login again to WEB UI interface and use my owncloud-client to synchronize content from my notebook to OwnCloud

 

This method should work work on resetting password of OwnCloud version 7, 8 and 9 on Linux (Fedora, Ubuntu, CentOS and RHEL) if OwnCoud was installed using rpm / deb packages. 
 

Run custom user script after reboot with a cronjob on Linux

Friday, September 21st, 2018

howto-add-custom-script-on-reboot-with-non-administrative-root-user-on-gnu-linux

Perhaps you have a websites on a server on some Linux distro / FreeBSD / AIX / HP-UX / Sun OS that uses Vixie-cron cron jobs to run / respawn dead php / python perl scripts etc.  that do stuff on the server every lets say 30 minutes an hour or even every 12 / 24 hours in the background.
But sometimes due to server or Linux kernel upgrades you need to reboot the server with reboot command or shutdown -r now right in the minutes the scripts were supposed to run and do a database backup / synchronize some data with a remote MySQL with replication configured or do some site maintenance job such as clearing old Messages / Spam / data log file records.

Of course one possible workaround to that is to add the non-root user scripts in question  to /etc/rc.local to run on every server boot, but that fix requires a root access and very often developers did not have that, neither sysadmins are willing to bother  add a user sudo-ed scripts e.g. add  (sudo -u whateveruser "/path/to/script") to /etc/rc.local.

Run custom user  script after reboot the cron way

Happily there is ctually a better cron way to do that by telling crond to execute a cronjob during boot and assuming the non-admin user on the Linux has access to shell and access to using cron jobs by using @reboot cron direcive.

Here is few examples on how to run a re-run cron job on start up:
 

linux:~$ crontab -e


Some editor as nano or vim will open listing all your previous set system jobs to add scripts phpjob.php

@reboot  /user/dir/path/to/phpjob
@reboot  /path/to/shell_script
@reboot  /path/to/linux-command

That's pretty shitty situation but thanksfully remote access of website username with SSH will be enough to set the right cron activity (of course this can't be made for servers that are missing crond service running.

The scripts set in cron job that way will respawn right after the OS system had booted and there will be no need for them to wait the next hour to execute configured data synch.
For more on how to run a tiny script respawn every second using a single cron job check out my previous article How to set a crontab to execute commands on a seconds time interval on GNU / Linux and FreeBSD.

Historically it is interestingly to mention that in times before systemd appeared in modern Linux distributions,
a cool thack to run a script that had to be respawned every second after boot for a privileged user was to use /etc/inittab (no longer available in most all non System V Linux distrubutions in 2018), to do so
if you happen to still administer some old Linux servers CentOS 7 etc. you and you need to add a custom script to run and respawn all the time by including a line in /etc/inittab (again assuming a System V Linux is on remote machine):
 

mysvc:235:respawn:/home/me/bin/my_service_starter_script

Putting a service to respawn in that way via inittab uses init (process) and the kernel and keeps re-running it.

Note: 

If a command fails when it starts, and init is configured to restart it, it will use a lot of system resources: init starts it, it fails, init starts it, it fails, init starts it, it fails, and so on, ad infinitum. To prevent this, init will keep track of how often it restarts a command, and if the frequency grows to high, it will delay for five minutes before restarting again.If the kernel 
Using inittab should always be tested on a testbed before adding to remote server, note that if the script is using a lot of memory and keeps crashing it can easily leave out the kernel without memory and the system is about to get errors like:
 

process respawning too fast 

 

Another useful thing if you have doubts that the script might be crashing is to use something like monit to monitor the script (assuming the script does provide some kind of tcp / udp connection on port) and report you via email / sms about issues with crashing script.
If you hear monit the first time I recommend you read my previous article Monitoring and restart server services (Apache, Mysql, Bind) with Monit to prevent server downtimes.

Install Jenkins software development automation server on GNU / Linux

Tuesday, September 18th, 2018

jenkins-automate-installation-on-logo-title

As I have gone through a hiring procedures for Dev Ops system administration (Senior System Engineer) positions in the largest IT company in Belarus EPAM (A Global provider for software engineering and IT consulting.one of the Dev Ops test tasks to do was to automate installation of Jenkins software development automation server on a Virtual Machine running Linust Guest of choice (VMWare / VirtualBox) with Ansible / Docker or Pure Shell Script as I love simplicity I choose to do it via Bash Shell script.

As Dev Ops position is more and more transforming into a programmer job into the New Age of non-sense Cloud Computing (I hate Clouds guys – I share Richard Stallman opinion that "Clouds are clouding your minds" !!! ) … the need for environments such as Jenkins allowing multiple pseudo "sys admins" (mostly copy / paste new age coders) to write and build there programs in Go Language / Python / Perl / Bash with a single environment for Continuous Integration (CI) that could deploy and keep software versionings in GitHub / Mercurial / SVN is exponentionally raising.

Old School Computer Geeks would definitely be amazed (reasonably) on why on earth would someone need a Web Based Java Crazy environment that Jenkins is to build a multiple language code and submit it to a source repository system
But as the people like to hype and make easy things harder adding more and more layers of complexity, the product is the new buziness hype terms Continuous Integration / Continuous Integration raise exponentially together with the softwares to do stuff.
As IT people are becoming more and more lazy and illitetelarete things like Jenkins is the next web development CI environment that is about to die in the coming 5 to 10 years.

Jenkins doesn't really cut the need for writting scrpits to make your application (Makefiles), for the Business Corporate world it is heavily used nowadays, because it is used to building projects using Web UI, running tests, doing static code analysis, and deploying.

What makes Jenkins in terms of IT architecture design solution is that every project that it builds is build via its Java Virtuam Machine Processor backend (the server itself runs in the background of the OS runs it through Java VM as a WAR file (Web Application Resource) with the help of Few Ruby and other scripted files.
Besides that JNS has in the moment of writting more than 1400 years spanning across platforms, UI, administration, source code management, and, most frequently, build management.

Jenkins is either used as a standalone server or as a servlet in Java app servers such as Tomcat.

This is the short script I came up with in bash that when executed installs Jenkins on the remote VM host server that ran Debian 9 Linux, the install_jenkins.sh script is downloadable here.

#!/bin/bash
# Install jenkins and test whether it runs prints password on prompt or send via email
# if email variable is set Jenkins password will be set to your email of choice using mail command
# NOTE: bsd-mailx package should be installed in order for email sent to work and local machine should be running a properly configured
# relay SMTP
# Author: Georgi Georgiev 
# hipo@pc-freak.net
email='hipo@mail.com';

add_repos_install_jenkins () {
apt-get install –yes -qq apt-transport-https git curl

wget -q -O – https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add –

if [ “$(sed -n ‘/jenkins/p’ /etc/apt/sources.list|wc -l)” -eq 0 ]; then
echo 'deb https://pkg.jenkins.io/debian binary/' >> /etc/apt/sources.list
fi

apt-get update -qq && apt-get install –yes -qq jenkins
}

check_j_install () {
if [ “$(dpkg –get-selections | cut -f1|grep -i jenkins)” ]; then echo 'succesfully installed'; 

else printf 'Problem in installing please check'; 
exit 1; 

fi

}

check_j_running_s_pass () {
if [ $(ps -e -o command|grep -i jenkins) ]; then 
echo 'Jenkins process working.'; 
echo ‘… do more here if necessery with some more commands’; 
else 
echo 'not working log to file' >> jenkins.log 
exit 1; 
fi

JENKINS_PASSWORD=`cat /var/lib/jenkins/secrets/initialAdminPassword`;
echo "Jenkins Admin password is $JENKINS_PASSWORD" | tee -a "jenkins_credentials.log";
if [ ! -z $email ]; then
echo $JENKINS_PASSWORD | mail -s "NEW Jenkins password" $email


fi

}

main () {
        add_repos_install_jenkins;
        check_j_install;
        check_j_running_s_pass;

}

main;

To run the script on the remote VM server started for the purpose I created a passwordless ssh key authentication with
 

ssh-keygen -t rsa


and 

 

ssh-copy-id -i ~/.ssh/id_dsa.pub root@remote-vm-host.com

 


command … for more check out my previous article "How to execute command to Multiple Servers / Establishing passwordless SSH key authentication on 50+ servers"

Once the passwordless authentication was established to remote Private Virtual Server I've used scp command to upload my install_jenkins.sh script with:

 

# scp -v install_jenkins.sh root@remote-vm-host.com:/root/install_jenkins.sh

Sending file modes: C0644 726 install_jenkins.sh
Sink: C0644 726 install_jenkins.sh
install_jenkins.sh              


Next to run the install_jenkins.sh on remote host I used remote SSH run command capability, the syntax goes like this:

 

 

 

ssh [USER-NAME]@[REMOTE-HOST] [command or script]


In that case the command I used was:

 

ssh root@remote-vm-host.com "chmod +x; /root/jenkins.sh"

 


Next I launched Firefox browser and accessed http://localhost:8080 on the VM host and used the long password generated from the script by command:

 

 

 

JENKINS_PASSWORD=`cat cat /var/lib/jenkins/secrets/initialAdminPassword`;


echo $JENKINS_PASSWORD

In the process of Initial Jenkins setup I selected the GitHub plugins necessery for me to connect Jenkins with GitHub WebHooks (for that perhaps I will write another article when I have time).

jenkins-plugin-installer-screenshot-linux-large

Jenkins Getting Started Initial Screen

jenkins-selecting-plugins-to-use-getting-started

Jenkins Selecting Plugins Screen

Once successfully set-up Jenkins Initial Project creation / Configuration ( Control Panel ) screen looks like so

jenkins-main-screen-successfully-deployed-on-gnu-linux

There was also a task to create a simple print Jenkins and Shell environment variables with a sample Jenkins Free Style Project.
Following 
the New Item menu and setting it to Execute Shell commands as a Build Parameters, the parameters set for the Jenkins Free Style Project to Print the Environment Varibles were like so:

 

 

 

 

 

 

#!/bin/sh

echo “Jenskins Environment Variables”

echo "BUILD_NUMBER" :: $BUILD_NUMBER

echo "BUILD_ID" :: $BUILD_ID

echo "BUILD_DISPLAY_NAME" :: $BUILD_DISPLAY_NAME

echo "JOB_NAME" :: $JOB_NAME

echo "JOB_BASE_NAME" :: $JOB_BASE_NAME

echo "BUILD_TAG" :: $BUILD_TAG

echo "EXECUTOR_NUMBER" :: $EXECUTOR_NUMBER

echo "NODE_NAME" :: $NODE_NAME

echo "NODE_LABELS" :: $NODE_LABELS

echo "WORKSPACE" :: $WORKSPACE

echo "JENKINS_HOME" :: $JENKINS_HOME

echo "JENKINS_URL" :: $JENKINS_URL

echo "BUILD_URL" ::$BUILD_URL

echo "JOB_URL" :: $JOB_URL

echo “===Linux Shell Variables ===”
env


Well, it wasn't really a rocket science was it?! 🙂

That's all folks, see you soon.

Mass substitute WordPress site Old domain URL to new URL in MySQL (MariaDB) database after website migration

Thursday, September 13th, 2018

mass-substitute-old-urls-to-new-urls-when-moving-wordpress-website-migrate-wordpress

Mass substitute WordPress site Old domain URL to new URL in MySQL (MariaDB) database after website migration

If you have just migrated a wordpress blog or site to a new server (domain URL) and you have many articles pointing to the old URL. Out of sudden the new domain will end up with many broken links and that would have a severe negative SEO effect on your website leading to a certain downfall of your number of daily unique visits.

Of course manually changing the URL links is achievable by going through all Published Posts when migrating small websites with 10-20 pages,  however it is an impossible tedious task you would definitely want to avoid when you're migrating large WP based websites with few hundred or thousands of posts / pages,
bacause this would be a few weeks of mindless repeatable job to go through each and every post and substite the broken URLs.

Fortunately with a little bit of SQL magic either through MySQL CLI or PHPMyAdmin (if the website is moved to a shared hosting where you have disabled access to MySQL (MariaDB) default connect tcp port 3306.

Depending on the type of WordPress or Website the old broken URLs might be located in various Database tables.
 

– So when Mass URL substitution is might be required ?


1. You migrate a Website http://what-ever-website.com with (PHP / CSS / HTML / Templates) etc. from Hosting Provider Hostgator.com to UK2.com (because the website target client changed lately to United Kingdom customers) to http://what-ever-website.co.uk and the site is moved to a new domain beacause of Business rebranding
 

2. Other reason for changing internal URLs from one URL to another might be if you're migrating your website from HTTP to HTTPS for security.

3. You are restructuring file storage / image directories on the server or due to migration of files to external CDN (Content Delivery Network).
For example (http://your-server.com/images/ , http://your-server.com/files )  URLs pointing to old website location subdirectory has to be changed to the new one (http://your-server.com/img/ , http://your-server.com/data)

 

– So what is the automated approach to solve the task of Mass URL substitution across WP site ?

 

  •  Create full backup of all your website database and double-check the backup (try to restore on a test (home) server or other hosting account to make sure the backup is consistent and restore would work normally if necessery
     
  • You can Create Backup either with mysqldump command tool manually … with the right command arguments or use some kind of script such as My tiny mysqlbackupper.sh shell script which I shared under my previous article Make daily MySQL on Linux backup with Shell Script  via PhpMyAdmin.


2. Change old website URL to new one directly from Database using MySQL text client
 

To change incorrect URL with the new correct one the general query to run is:

 

update TABLE_NAME set FIELD_NAME = replace(FIELD_NAME, ‘find string’, ‘replace string’);

 

To change old website URL to the new website URL across every table within the wordpress database use below queries:
 

hipo@linux:~$ mysql -u root -p
Enter password:

 

USE blog;

 

UPDATE wp_options SET option_value = replace(option_value, 'Existing (old) URL', 'New URL') WHERE option_name = 'home' OR option_name = 'siteurl';

UPDATE wp_posts SET post_content = replace(post_content, 'Existing (old)URL', 'New URL');

UPDATE wp_postmeta SET meta_value = replace(meta_value,'Existing (old) URL','New URL');

UPDATE wp_usermeta SET meta_value = replace(meta_value, 'Existing (old) URL','New URL');

UPDATE wp_links SET link_url = replace(link_url, 'Existing (old) URL','New URL');

UPDATE wp_comments SET comment_content = replace(comment_content , 'Existing (old) URL','New URL');


3. Replace Old website URL to New one after migration using PHPMyAdmin web interface
 

If you don't have access  ssh shell, you can also run the queries via PhpMyAdmin to do so:

1. Open PHPMyadmin URL Panel in browser and login with your user / pass

2. Choose the wordpress database of the wordpress site / blog

3. Select SQL tab and in the panel type on above given SQL queries
 

web-hosting-phpmyadmin-sql-query-tab-screenshot-how-to-run-sql-queries-via-phpmyadmin

If you're lazy to type there is also a web based SQL queries generator tool for moving websites to a new domain


4. Using Search and Replace WordPress plugin to do the old URL to new URL (strings) transition
 

If you have never used SQL queries and you're totally new to it and don't want to risk breaking up something there is also a bunch of wordpress plugins available that do the URL string substitution throughout each wordpress table in a WP database one such WordPress plugin is Search and Replace I have written earlier an article Change string in all WordPress Posts with Search and Replace plugin.


5. Problems with data-serialization
 

If you do a simple search and replace of Old domain urls to New ones, using above given commands and you still end up with some broken links on WP Pages that might be due to data-serialization issues (for the cause of issues check out what is data serialization).
Data serialization in wordpress terms is an array of PHP encrypted data that contains the actual URL, thus a simple search and replace as explained above if URLs use data-serialization would not work. There are available tools online that does URL search and replace operation through  "serialize-data sensitively" if you stuck with data-serializatoin caused issues.

Besides that for there are written scripts that does URL substitution to a WordPress or Joomla websites so an alternative to above WP plugin to replace the URL after migration is to use one of the scripts available a very famous one that will do pain-free all URL / string substitutions inside your WP, Drupal,  Joomla databses is interconnect/it.
 

Few closure words
 

As a system administrator and webmaster I have migrated wordpress installations many times with the need to change the old URLs to a new ones for both customer websites and my own wordpress based. On many ocassions because of lack of attention and hurry, I've messed up things.
The moral I got out of this is when you're doing a WordPress migration just like everything you have to be very attentive and do everything step by step slowly and have a good idea on what you're doing in advance …

Even as a person who had overall idea on how MySQL Server works and have experience in writting SQL queries, I have to confess I've  made mistakes during URL substitution operations when doing it via the MySQL CLI every now and then.

Thus I would recommend you better use some of the many plugins for wordpress and script tools (few of which I mentioned above), especially if you're not having at least few years with some kind of UNIX variation / Linux / MySQL.

Optimize PNG images by compressing on GNU / Linux, FreeBSD server to Improve Website overall Performance

Monday, November 27th, 2017

how-to-optimize-your-png-pictures-to-reduce-size-and-save-speed-bandwidth-optipng-compression-tests-results

If you own a website with some few hundreds of .PNG images like 10 000 / 15 000 png images and the website shows to perform slow in Google PageSpeed Insights and is slow to open when Google Searched or Shared on Facebook / Twitter etc. then one recommended step to boost up the website opening speed is to compress (optimize) the .PNG pictures without loosing the images quality to both save space and account bandwidth you could use optipng even though this is not the only tool available to help you optimize and reduce the size of your images, some few other tools you might like to check out if you have more time are:

 a.)  pngcrush – optimizes PNG (Portable Network Graphics) files.
 b.)  pngnq – tool for optimizing PNG (Portable Network Graphics) images. It is a tool for quantizing PNG images in RGBA format.
 c.)  pngquant – PNG (Portable Network Graphics) image optimising utility. It is a command-line utility for converting 24/32-bit PNG images to paletted (8-bit) PNGs.
 

1. Install and Compress / optimize PNG / GIF / PNM / TIFF file format with optipng
 

OPTIPING tool recompresses the .PNG images to a smaller size without loosing any quality information, besides PNG file format it also supports (BMP, GIF, PNM and TIFF) image format.

If you don't have optipng installed on your server you can;

a.) install it on Redhat RPM based Linux distributions lets say CentOS Linux use:

 

[root@centos: ~]# yum install epel-release
[root@centos: ~]# yum install optipng

Note that, You will need to  first enable epel repo on centos 7

 

b.) If instead you're on a Debian GNU / Linux

debian:~# apt-get install optipng


c.) FreeBSD users can install it from FreeBSD ports with:

 

freebsd# cd /usr/ports/graphics/optipng
freebsd# make install clean

optipng syntax is quite self explanatory
optipng [options] what-ever-file.png


You can get a full list of possible command options with -? command, here is a list:

 

debian:~# optipng -?
Synopsis:
    optipng [options] files …
Files:
    Image files of type: PNG, BMP, GIF, PNM or TIFF
Basic options:
    -?, -h, -help    show this help
    -o <level>        optimization level (0-7)        [default: 2]
    -v            run in verbose mode / show copyright and version info
General options:
    -backup, -keep    keep a backup of the modified files
    -clobber        overwrite existing files
    -fix        enable error recovery
    -force        enforce writing of a new output file
    -preserve        preserve file attributes if possible
    -quiet, -silent    run in quiet mode
    -simulate        run in simulation mode
    -out <file>        write output file to <file>
    -dir <directory>    write output file(s) to <directory>
    -log <file>        log messages to <file>
    —            stop option switch parsing
Optimization options:
    -f <filters>    PNG delta filters (0-5)            [default: 0,5]
    -i <type>        PNG interlace type (0-1)
    -zc <levels>    zlib compression levels (1-9)        [default: 9]
    -zm <levels>    zlib memory levels (1-9)        [default: 8]
    -zs <strategies>    zlib compression strategies (0-3)    [default: 0-3]
    -zw <size>        zlib window size (256,512,1k,2k,4k,8k,16k,32k)
    -full        produce a full report on IDAT (might reduce speed)
    -nb            no bit depth reduction
    -nc            no color type reduction
    -np            no palette reduction
    -nx            no reductions
    -nz            no IDAT recoding
Editing options:
    -snip        cut one image out of multi-image or animation files
    -strip <objects>    strip metadata objects (e.g. "all")
Optimization levels:
    -o0        <=>    -o1 -nx -nz                (0 or 1 trials)
    -o1        <=>    -zc9 -zm8 -zs0 -f0            (1 trial)
            (or…)    -zc9 -zm8 -zs1 -f5            (1 trial)
    -o2        <=>    -zc9 -zm8 -zs0-3 -f0,5            (8 trials)
    -o3        <=>    -zc9 -zm8-9 -zs0-3 -f0,5        (16 trials)
    -o4        <=>    -zc9 -zm8 -zs0-3 -f0-5            (24 trials)
    -o5        <=>    -zc9 -zm8-9 -zs0-3 -f0-5        (48 trials)
    -o6        <=>    -zc1-9 -zm8 -zs0-3 -f0-5        (120 trials)
    -o7        <=>    -zc1-9 -zm8-9 -zs0-3 -f0-5        (240 trials)
    -o7 -zm1-9    <=>    -zc1-9 -zm1-9 -zs0-3 -f0-5        (1080 trials)
Notes:
    The combination for -o1 is chosen heuristically.
    Exhaustive combinations such as "-o7 -zm1-9" are not generally recommended.
Examples:
    optipng file.png                        (default speed)
    optipng -o5 file.png                    (slow)
    optipng -o7 file.png                    (very slow)

Just running it with, lets say -o7 arguments is enough for optipng to compress your image and reduce some 15 to 30% of picture size

optipng -o7 what-ever-image-you-have.png

optipng-example-on-reducing-image-screenshot-24.9-png-image-compression

2. Compress images without loosing quality recursively inside directory and subdirectories with optiping

a.) To optimize all pictures inside a single directory (without sub-directories) on remote server you can run, below command:
 

cd whatever-dir/
for i in *.png; do optipng -o6 -quiet -keep -preserve -dir optimized -log optipng-compress.log "$i"; done


As you can see a log is being written on what the command has done and the originals of the optimized images is going to be preserved, the optimize level is 6 is the PNG encoding level.

 

cd /var/www/your-site/images/
find . -type f -iname "*.png" -print0 | xargs -I {} -0 optipng -o6 -keep -preserve -log optipng-compress.log "{}"


This command is pretty handy to run on own dedicated server, if you don't have one just do it on your Linux computer at home or if you don't own a PC with Linux install any Deb / RPM based Linux inside VirtualBox or VMWare Virtual Machine and do it there, then upload to your Hosting Provider / Amazon EC2 etc and Enjoy the increased website performance 🙂

 

Add gzip compression to optimize web server served files in Apache, Nginx and LiteSpeed

Wednesday, November 15th, 2017

Enable-Gzip-Compression-quick-howto-on-apache-nginx-litespeed

What is GZIP Compression and why you need it?

no-gzip-support-illustration

  • What is gzip? – In Linux / Unix gzip of files is used to compress files so they can take less space when they're transferred from server to server via network in order to speed up file transfer.
  • Usually gzipped files are named as filename.gz
  • Why GZIp compression is important to be enabled on servers, well because that reduces the transferred (served) file by webserver to client browser
  • The effect of this is the faster file transfer of the file and increased overall web user performance


how-gzip-works-with-nginx-illustrated

Most webservers / websites online currently use gzipping of a sort, those who still did not use it has websites which are up to 40% slower than those of competitor websites

How to enable GZIP Compression on Apache Webserver

The easiest way for most people out there who run there websites on a shared hosting is to add the following Apache directives to dynamic loadable .htaccess file:
 

<ifModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>

 

You can put a number of other useful things in .htaccess the file should already be existing in most webhostings with Cpanel or Kloxo kind of administration management interface.

Once the code is included to .htaccess you can reflush site cache.
To test whether the just added HTTP gzip compression works for the Webserver you can use The Online HTTP Compression test

If for some reason after adding this code you don't rip the benefits of gzipped content served by webserver you can try to add altenatively to .htaccess

 

AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript

 


Howto Enable GZIP HTTP file compression on NGINX Webserver?

Open NGINX configuration file and add to it the following command parameters:

 

gzip on;
gzip_comp_level 2;
gzip_http_version 1.0;
gzip_proxied any;
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

 

# Disable for IE < 6 because there are some known problems
gzip_disable "MSIE [1-6].(?!.*SV1)";

# Add a vary header for downstream proxies to avoid sending cached gzipped files to IE6
gzip_vary on;

Enable HTTP file Compression on LiteSpeed webserver

In configuration under TUNING section check whether "enable compression" is enabled, if it is not choose "Edit"
and turn it on.

litespeed-how-to-enable-gzip-compressible_type-illustrated

What is the speed benefits of using HTTP gzip compression?

By using HTTP gzip compression you can save your network and clients abot 50 to 70% (e.g. transferred data) of the original file size.
This would mean less time for loading pages and fetched files and decrease in used bandwidth.

effect-of-gzip-compression-diagram-illustrated

A very handy tool to test whether HTTP Compression is enabled as well as how much is optimized for Speed your Website is Google PageSpeed Insights
as well as GTMetrix.com

Where are Apache log files on my server – Apache log file locations on Debian / Ubuntu / CentOS / Fedora and FreeBSD ?

Tuesday, November 7th, 2017

apache-where-are-httpd-access-log-files

Where are Apache log files on my server?

1. Finding Linux / FreeBSD operating system distribtion and version

Before finding location of Apache log files it is useful to check what is the remote / local Linux operating system version, hence

First thing to do when you login to your remote Linux server is to check what kind of GNU / Linux you're dealing with:

cat /etc/issue
cat /etc/issue.net


In most GNU / Linux distributions should give you enough information about the exact Linux distribution and version remote server is running.

You will get outputs like

# cat /etc/issue
SUSE LINUX Enterprise Server 10.2 Kernel \r (\m), \l

or

# cat /etc/issue
Debian GNU/Linux 8 \n \l

If remote Linux is Fedora look for fedora-release file:

cat /etc/fedora-release Fedora release 7 (Moonshine)

The proposed freedesktop.org standard with the introduction of systemd across all Linux distributions is

/etc/os-release

 

# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 8 (jessie)"
NAME="Debian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=debian
HOME_URL="http://www.debian.org/"
SUPPORT_URL="http://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"


Once we know what kind of Linux distribution we're dealing with, we can proceed with looking up for standard location of Apache config:

2. Apache config file location for Fedora / CentOS / RHEL and other RPM based distributions

RHEL / Red Hat / CentOS / Fedora Linux Apache access file location
 

/var/log/httpd/access_log


3. Apache config file location for Debian / Ubuntu and other deb based Linux distributions

Debian / Ubuntu Linux Apache access log file location

/var/log/apache2/access.log


4. Apache config file location for FreeBSD

FreeBSD Apache access log file location –

/var/log/httpd-access.log


5. Finding custom Apache access log locations
 

If for some reason the system administrator on the remote server changed default path for each of distributions, you can find custom configured log files through:

a) On Debian / Ubuntu / deb distros:

debian:~# grep CustomLog /etc/apache2/apache2.conf


b) On CentOS / RHEL / Fedora Linux RPM based ones:

[root@centos:  ~]# grep CustomLog /etc/httpd/conf/httpd.conf


c) On FreeBSD OS

 

freebsd# grep CustomLog /etc/httpd/conf/httpd.conf
 # a CustomLog directive (see below).
    #CustomLog "/var/log/httpd-access.log" common
    CustomLog "/var/log/httpd-access.log" combined