sudo apt-cache search apache2 | grep libapache2-mod-fcgi
Note: sudo apt install libapache2-mod-fcgi (not working now. 2019)
sudo apt install libapache2-mod-fcgid -y (working...2020 )
cd /tmp && wget https://mirrors.edge.kernel.org/ubuntu/pool/multiverse/liba/libapache-mod-fastcgi/libapache2-mod-fastcgi_2.4.7~0910052141-1.2_amd64.deb
sudo dpkg -i libapache2-mod-fastcgi_2.4.7~0910052141-1.2_amd64.deb
Start:
sudo systemctl start apache2.service
service apache2 start
Status:
sudo systemctl status apache2
service apache2 status
Restart:
sudo systemctl restart httpd
sudo systemctl restart apache2.service
service apache2 restart
Reload:
sudo systemctl reload apache2.service
service apache2 reload
Stop:
sudo systemctl stop apache2.service
Configuration files:
Redhat: /etc/httpd/conf/httpd.conf
/etc/apache2/apache2.conf – This is the main Apache configuration file and controls everything Apache does on your system. Changes here affect all the websites hosted on this machine.
/etc/apache2/ports.conf – The port configuration file. You can customize the ports Apache monitors using this file. By default, Port 80 is configured for Http traffic.
/etc/apache2/sites-available – Storage for virtual host files. A virtual host is a record of one of the websites hosted on the server.
/etc/apache2/sites-enabled – This directory holds websites that are ready to serve clients. The a2ensite command is used on a virtual host file in the sites-available directory to add sites to this location.
Default webroot: /var/www/html/
*** Checking the inbound rules from the EC2 dashboard, from below we can see that only the “PORT 22” is open, which is only for “SSH“.
See the ufw firewall section.
Install Modules:
a2enmod proxy_http
a2enmod proxy
PHP 7.4 (fpm - Fast Process Manager)
sudo apt update && sudo apt upgrade -y
sudo apt-cache search php7.2 | grep php
To verify if PHP is installed already, in the command line, type:
php -v
$ sudo apt-get install php7.4-fpm php7.4-mysql php7.4-mbstring php7.4-curl php7.4-dom -y
For Magento General PHP install with req modules: (replace the php7.2 with the phpfpm one)
$ sudo apt-get install php7.2 libapache2-mod-php7.2 php7.2-common php7.2-gd php7.2-mysql php7.2-curl php7.2-intl php7.2-xsl php7.2-mbstring php7.2-zip php7.2-bcmath php7.2-iconv php7.2-soap -y
For Magento with FPM only
$ sudo apt install php7.4-fpm libapache2-mod-php7.4 php7.4-common php7.4-gd php7.4-mysql php7.4-curl php7.4-intl php7.4-xsl php7.4-mbstring php7.4-zip php7.4-bcmath php7.4-iconv php7.4-soap -y
php -v
Laravel Server Requirements mention that BCMath, Ctype, JSON, Mbstring, OpenSSL, PDO, Tokenizer, and XML extensions are required. Most of the extensions are installed and enabled by default.
PHP version-specific installation (if PHP 7.4 installed)
sudo apt-get install zip unzip php-zip
sudo apt install
php7.4-fpm php7.4-common php7.4-bcmath openssl php7.4-json php7.4-mbstring php-xml php-mysql php7.4-curl -y
sudo phpenmod pdo_mysql
libapache2-mod-php7.4
sudo apt-cache search apache2 | grep libapache2-mod-e
$ sudo apt install php7.3-fpm libapache2-mod-php7.3 php7.3-common php7.3-gd php7.3-mysql php7.3-curl php7.3-intl php7.3-xsl php7.3-mbstring php7.3-zip php7.3-bcmath php7.3-iconv php7.3-soap -y
Verify that all required PHP extensions were installed:
sudo php -me
and check "Server API Apache 2.0 Handler" that is PHP-FPM is not configured yet!
To locate the PHP command-line configuration, enter
php --ini | grep "Loaded Configuration File"
Configure Apache with PHP-fpm on Ubuntu 20
Right now, Our Apache web server and PHP-FPM are configured and can work individually. But we still have to tell our Apache webserver to pass PHP requests to PHP fast process manager.
To enable PHP 7.4 FPM in Apache2 do (after php7.2-fpm installed): [If disable the older version of PHP (a2dismod [oldversion])] [Edit for 7.* if version changed]
sudo cat /etc/apache2/conf-available/php7.4-fpm.conf
sudo cp /etc/apache2/conf-available/php7.4-fpm.conf /etc/apache2/conf-available/php7.4-fpm.conf.orginal
sudo vi /etc/apache2/conf-available/php7.4-fpm.conf
<IfModule mod_fastcgi.c>
AddHandler php7-fcgi .php
Action php7-fcgi /php7-fcgi
Alias /php7-fcgi /usr/lib/cgi-bin/php7-fcgi
FastCgiExternalServer /usr/lib/cgi-bin/php7-fcgi -socket /var/run/php/php7.4-fpm.sock -pass-header Authorization -idle-timeout 60
<Directory /usr/lib/cgi-bin>
Require all granted
</Directory>
</IfModule>
Test conf script for errors:
sudo apache2ctl configtest
PHP 7.4 FPM disabled by default. To enable PHP 7.4 FPM in Apache2 do:
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php7.4-fpm
sudo a2enmod actions expires
sudo systemctl restart apache2
sudo systemctl reload apache2
The module proxy_fcgi provides support for the FastCGI protocol. The associated setenvif sets the variables sent to the FastCGI.
sudo systemctl restart php7.4-fpm apache2
sudo service php7.4-fpm status
Making a new website with a domain
Make a particular user for a particular site standard practice and also put him to the www group.
sudo mkdir -p /var/www/ejamuna.com
Then assign the ownership of the directory to Apache2 through the following commands:
Is Apache running as www-data?
ps axu | grep -E 'apache|www-data|http'
sudo chown -R <www-data>:www-data /var/www/ejamuna.com
no need: sudo chmod -R 755 /var/www/ejamuna.com
Change the group ownership of /var/www
and its contents to the apache
group.
[ec2-user ~]$
sudo chown -R ec2-user:apache /var/www
To add group write permissions and to set the group ID on future subdirectories, change the directory permissions of /var/www
and its subdirectories.
[ec2-user ~]$
sudo chmod 2775 /var/www && find /var/www -type d -exec sudo chmod 2775 {} \;
To add group write permissions, recursively change the file permissions of /var/www
and its subdirectories:
[ec2-user ~]$
find /var/www -type f -exec sudo chmod 0664 {} \;
Create HTML file:
echo "ejamuna!" > /var/www/ejamuna.com/index.php
or
sudo vi /var/www/ejamuna.com/j.php
<h1>eJamuna!</h1>
<?php
phpinfo();
?>
If you want to change Apache to serve PHP files rather than others, move index.php to first position in the dir.conf file as shown below:
sudo vi /etc/apache2/mods-enabled/dir.conf
Apache needs a virtual host file to serve the contents of your domain from the server.
sudo vi /etc/apache2/sites-available/ejamuna.com.conf
<VirtualHost *:80>
ServerAdmin webmaster@ejamuna.com
ServerName ejamuna.com
ServerAlias www.ejamuna.com
DocumentRoot /var/www/ejamuna.com
#ProxyPass / http://localhost:3000/
#ProxyPassReverse / http://localhost:3000/
<Directory "/var/www/ejamuna.com">
AllowOverride All
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php7.4-fpm.sock|fcgi://localhost/"
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/ejamuna.com-error.log
CustomLog ${APACHE_LOG_DIR}/ejamuna.com-access.log combined
</VirtualHost>
Test for errors:
sudo apache2ctl configtest
Enable the domain configuration file:
sudo a2ensite ejamuna.com.conf
a2ensite 000-default.conf
a2ensite default-ssl.conf
To disable a website:
sudo a2dissite 000-default.conf
sudo systemctl reload apache2
sudo service apache2 reload
Handy codes:
sudo mkdir /var/www/ejamuna.com
sudo chown -R <www-data>:www-data /var/www/ejamuna.com
SSL
Update Your System–Frequently
sudo apt update && sudo apt upgrade -y
Enable the universe repository
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo apt-get update
Install the Certbot
Run this command on the command line on the machine to install Certbot.
sudo apt-get install certbot python3-certbot-apache
Version (24 Jun, 2020)
certbot --version
My version of certbot was 0.40.0
Get a certificate with Route 53 plugin
Install correct DNS plugin
-sudo apt install python3-certbot-dns-<PLUGIN>
sudo apt install python3-certbot-dns-route53
Manual
The access keys for an account with these permissions must be supplied in one of the following ways, which are discussed in more detail in the Boto3 library’s documentation about configuring credentials.
Examples:
certbot certonly \
--dns-route53 \
--dns-route53-propagation-seconds 30 \
-d example.com \
-d www.example.com
Install certificate Manually( without Plugins)
Ref:
Generate Strong Dh (Diffie-Hellman) Group
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Obtaining a Let’s Encrypt SSL certificate
sudo vi /etc/apache2/conf-available/letsencrypt.conf
Alias /.well-known/acme-challenge/ "/var/lib/letsencrypt/.well-known/acme-challenge/"
<Directory "/var/lib/letsencrypt/">
AllowOverride None
Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
Require method GET POST OPTIONS
</Directory>
sudo vi /etc/apache2/conf-available/ssl-params.conf
# SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:\
ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA256:\
ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:\
ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA256:\
ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:\
DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder On
# Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
# Requires Apache >= 2.4
SSLCompression off
# Requires Apache >= 2.4.11
SSLSessionTickets Off
# Activate OCSP stapling on Apache 2.4+
# https://www.tbs-certificates.co.uk/FAQ/en/active-ocsp-apache.html
# SSLUseStapling on
# SSLStaplingCache "shmcb:logs/stapling_cache(128000)"
SSLStaplingCache shmcb:/var/tmp/ocsp-stapling-cache/cache(128000000)
SSLUseStapling on
SSLStaplingResponderTimeout 2
SSLStaplingReturnResponderErrors off
SSLStaplingFakeTryLater off
SSLStaplingStandardCacheTimeout 86400
# https://www.tbs-certificates.co.uk/FAQ/en/install-cert-ssl-apache-2-4-8.html
SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem"
SSLOpenSSLConfCmd ECDHParameters secp384r1
# https://httpd.apache.org/docs/current/mod/mod_ssl.html
SSLOptions +StrictRequire
# Add vhost name to log entries:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined
LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common
Test for errors:
sudo apache2ctl configtest
Enable these mods:
sudo a2enmod ssl headers
Enable these scripts:
sudo a2enconf letsencrypt ssl-params
Enable these mods:
sudo a2enmod http2 rewrite
Reload Apache2:
sudo systemctl reload apache2 (conf)
sudo systemctl restart apache2 (mod)
sudo service apache2 reload
Apache Status checking:
sudo systemctl status apache2
sudo mkdir -p /var/lib/letsencrypt/
sudo chgrp www-data /var/lib/letsencrypt
sudo chmod g+s /var/lib/letsencrypt
sudo mkdir -p /var/lib/letsencrypt/.well-known/acme-challenge/
sudo chmod -R 775 /var/lib/letsencrypt
Testing the setup:
sudo gpasswd -a tommy_user javagroup (add user to a group)
sudo echo -n "Testing acme-challenge" > /var/lib/letsencrypt/.well-known/acme-challenge/test
sudo curl -ikL http://www.ejamuna.com/.well-known/acme-challenge/test
Setting directories with g+s makes all new files created in the said directory have their group set to the directory's group. When used on a directory, instead, the setgid bit alters the standard behaviour so that the group of the files created inside said directory, will not be that of the user who created them, but that of the parent directory itself. This is often used to ease the sharing of files (files will be modifiable by all the users that are part of said group).
This can actually be really handy for collaborative purposes if you have the umask set so that files have group write by default.
Obtain the certificate
Getting a certificate:
certbot certonly \
-d example.com \
-d *.example.com \
--dns-route53 \
--logs-dir /home/username/letsencrypt/log/ \
--config-dir /home/username/letsencrypt/config/ \
--work-dir /home/username/letsencrypt/work/ \
-m email@example.com \
--agree-tos \
--server https://acme-v02.api.letsencrypt.org/directory
Renew example:
certbot renew --dns-route53 \
--logs-dir /home/username/letsencrypt/log/ \
--config-dir /home/username/letsencrypt/config/ \
--work-dir /home/username/letsencrypt/work/ \
--server https://acme-v02.api.letsencrypt.org/directory \
--post-hook "sudo service nginx reload"
dns-route53 plugin: certbot website
sudo certbot certonly \
-i apache \
--dns-route53 \
--dns-route53-propagation-seconds 30 \
-d dumbschool.com \
-d www.dumbschool.com \
--agree-tos \
--email bdjunayed@gmail.com
Webroot: authenticator plugin (Single domain)
sudo certbot certonly \
-i apache \
-a webroot \
-w /var/www/haanz.online/ \ -w /var/lib/letsencrypt/ \
-d haanz.online \
-d www.haanz.online \
--email bdjunayed@gmail.com \
--agree-tos \
--server https://acme-v02.api.letsencrypt.org/directory
Webroot: authenticator plugin (to obtain a single certificate for multiple domains)
To use the webroot plugin, your server must be configured to serve files from /.well-known
sudo certbot certonly \
--webroot \
-w /var/www/d1.com \
-d d1.com \
-w /var/www/d2.com \
-d d2.com
--agree-tos \
--email bdjunayed@gmail.com \
Manual: kind of webroot plugin but manual.
sudo certbot certonly \
--preferred-challenges=dns \
--manual
-d example.com \
-d www.example.com \
Manual: (CrazyDomain don't allow the TXT record)
sudo certbot certonly \
--preferred-challenges=http \
--manual \
-d saustralasia.online \
-d www.saustralasia.online \
--email bdjunayed@gmail.com \
--agree-tos \
--server https://acme-v02.api.letsencrypt.org/directory
Successful output sample:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Cert not yet due for renewal
You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry.
(ref: /etc/letsencrypt/renewal/saustralasia.online.conf)
What would you like to do?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Keep the existing certificate for now
2: Renew & replace the cert (limit ~5 per 7 days)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Renewing an existing certificate
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/saustralasia.online/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/saustralasia.online/privkey.pem
Your cert will expire on 2020-03-30. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
root@node1:~#
Now, you have the certificate files, edit your domain virtual host configuration as follows:
Ref:
sudo vi /etc/apache2/sites-available/ejamuna.com.conf
<VirtualHost *:80>
ServerAdmin admin@ejamuna.com
ServerName ejamuna.com
ServerAlias www.ejamuna.com
DocumentRoot /var/www/ejamuna.com/pub
<Directory /var/www/ejamuna.com>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
#ProxyPass / http://localhost:3000/
#ProxyPassReverse / http://localhost:3000/
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php7.4-fpm.sock|fcgi://localhost/"
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/ejamuna.com-error.log
CustomLog ${APACHE_LOG_DIR}/ejamuna.com-access.log combined
#Redirect permanent / https://ejamuna.com/
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.ejamuna.com [OR]
RewriteCond %{SERVER_NAME} =ejamuna.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName ejamuna.com
ServerAlias www.ejamuna.com
ServerAdmin admin@ejamuna.com
Protocols h2 http:/1.1
#<If "%{HTTP_HOST} == 'www.ejamuna.com'">
# Redirect permanent / https://ejamuna.com/
#</If>
DocumentRoot /var/www/ejamuna.com/pub
# Apache 2.4 If you are not the administrator of the server, you depend
# on the AllowOverride Level that theses admins allows for you.
<Directory /var/www/ejamuna.com>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
#ProxyPass / http://localhost:3000/
#ProxyPassReverse / http://localhost:3000/
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php7.4-fpm.sock|fcgi://localhost/"
</FilesMatch>
# Allow encoded slashes
AllowEncodedSlashes NoDecode
ErrorLog ${APACHE_LOG_DIR}/ejamuna.com-error.log
CustomLog ${APACHE_LOG_DIR}/ejamuna.com-access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
SSLEngine On
# Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/ejamuna.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/ejamuna.com/privkey.pem
# SSLCertificateChainFile /etc/letsencrypt/live/saustralasia.online/chain.pem (Obsolute)
Header always set Strict-Transport-Security "max-age=31536000"
Header always set Content-Security-Policy upgrade-insecure-requests
</VirtualHost>
</IfModule>
Test for errors:
sudo apache2ctl configtest
Reload Apache2 for conf:
sudo service apache2 reload
Test your certificate:
Auto-renewing Let’s Encrypt SSL certificate
Ref:
Certbot documentation
Let’s Encrypt’s certificates are valid for 90 days. To automatically renew the certificates before they expire, the certbot package creates a cronjob which runs twice a day and will automatically renew any certificate 30 days before its expiration.
FIY, it will dry-run for all the domains already added.
Once the certificate is renewed we also have to reload the Apache service. Append --renew-hook "systemctl reload apache2" to the /etc/cron.d/certbot file so that it looks like the following:
sudo vi /etc/cron.d/certbot
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew --renew-hook "systemctl reload apache2"
--renew-hook "systemctl reload apache2"
Test automatic renewal:
sudo certbot renew --dry-run
Delete cert:
sudo certbot delete --cert-name dumbschool.com
List cert:
sudo certbot certificates
Certbot troubleshoots:
grep -r 443 /etc/apache2
Dismental a site:
sudo apache2ctl configtest
sudo certbot certificates
sudo certbot delete --cert-name saustralasia.online
sudo a2dissite saustralasia.online.conf
sudo service apache2 reload
sudo service apache2 status
Installing Composer
Prerequisite: Php
Installing Globally
Run as a sudo user
sudo php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
sudo php -r "if (hash_file('sha384', 'composer-setup.php') === 'e0012edf3e80b6978849f5eff0d4b4e4c79ff1609dd1e613307e16318854d24ae64f26d17af3ef0bf7cfb710ca74755a') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
sudo php composer-setup.php
sudo php -r "unlink('composer-setup.php');"
sudo mv ~/composer.phar /usr/local/bin/composer
or
sudo mv composer.phar /usr/local/bin/composer
or
mg@node1:~$ sudo mkdir -p ~/bin/composer
mg@node1:~$ sudo mv composer.phar ~/bin/composer/
sudo vi ~/.bashrc
alias composer='/home/mg/bin/composer/composer.phar'
For Local changes:
source ~/.bashrc
For Global Changes:
sudo vi /etc/bash.bashrc
To update Composer itself
/usr/local/bin/composer/composer.phar self-update
Uninstall composer?
Changing your PATH
Check the current path settings:
mg@node1:~$ echo $PATH
Simply add /place/with/the/file to the $PATH variable with the following command:
export PATH=$PATH:/place/with/the/file
Check which shell is running
echo $0
Set your PATH permanently
A file called ~/.bash_profile, ~/.bashrc, or ~/.profile. ~/.bashrc is a good choice.
#added to set the PATH
PATH=$PATH:/home/mg/composer.phar
To test your path, run
composer --version
See these also (if not required):
The COMPOSER_HOME var allows you to change the Composer home directory. This is a hidden, global (per-user on the machine) directory that is shared between all projects.
echo $COMPOSER_HOME
echo $COMPOSER_BIN_DIR