Install (EL9 has Mariadb 10.5 version):
# dnf install -y mariadb-server # vim /etc/my.cnf.d/mariadb-server.cnf [mysqld] ... character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci innodb_file_format = Barracuda innodb_file_per_table = on innodb_default_row_format = dynamic innodb_large_prefix = 1 # systemctl start mariadb.service && systemctl enable mariadb.service && systemctl status mariadb.service # mysql_secure_installation Enter current password for root (enter for none): <Enter> Switch to unix_socket authentication [Y/n] <Enter> Set root password? [Y/n] <Enter> New password: <your_new_root_password> Re-enter new password: <your_new_root_password> Remove anonymous users? [Y/n] <Enter> Disallow root login remotely? [Y/n] <Enter> Remove test database and access to it? [Y/n] <Enter> Reload privilege tables now? [Y/n] <Enter>
Note: root user has by default password-less access via socket, can be verified with:
# mysql -u root > SHOW GRANTS FOR 'root'@'localhost';
# dnf install -y nginx # systemctl start nginx && systemctl enable nginx && systemctl status nginx # vim /etc/nginx/nginx.conf # vim /etc/nginx/nginx.conf http { ... #if we want to support big image uploads, match php.ini .... client_max_body_size 10M; #it's good to put this default here index index.html index.htm index.php; #enable caching, most important lines are gzip on; and gzip_types; gzip on; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript; gzip_disable "msie6"; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; server { # we might want to specify other default homepage of server so we dont give attacker any info #root /usr/share/nginx/html; root /var/www/html; location / { index index.html index.htm; } } } # mkdir -p /var/www/html # echo "cd" > /var/www/html/index.html # systemctl restart nginx && systemctl status nginx
Check in browser: http://<ip_address>
# useradd -m example # passwd example # usermod -a -G nginx example # mkdir /home/example/html # echo "<?php phpinfo(); ?>" > /home/example/html/index.php # chown example.example -R /home/example/html # chmod 755 /home/example
Install epel:
# dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm # rpm -qa | grep epel
Install remi:
# dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm # rpm -qa | grep remi
Make sure no php is installed:
# yum list installed | grep php # yum remove --noautoremove php php-common ...
Switch php module to remi and install:
# dnf module list php # dnf module reset php # dnf module enable php:remi-7.4 # dnf install php php-fpm php-mysqlnd php-cli php-xml php-gd php-pecl-zip php-opcache php-intl php-process php-mbstring php-bcmath php-pecl-ds php-json php-gmp # php -v
Set up php-fpm ...
# vim /etc/php.d/50-custom.ini ;optional tweak - performance in symfony app realpath_cache_ttl = 600 ;optional tweak - lot of times we need more memory memory_limit = 256M ;optional tweak - error reporting adjust error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE ;optional tweak post_max_size = 12M ;optional tweak upload_max_filesize = 10M ;set default PHP timezone date.timezone = America/New_York ;for typical symfony app, default number is low opcache.max_accelerated_files=20000 # cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.default # mv /etc/php-fpm.d/www.conf /etc/php-fpm.d/example.conf # vim /etc/php-fpm.d/example.conf [example] user = example group = example listen = 127.0.0.1:9001 listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 50 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 35 slowlog = /var/log/php-fpm/example-slow.log php_admin_value[error_log] = /var/log/php-fpm/example-error.log php_admin_flag[log_errors] = on php_value[session.save_handler] = files php_value[session.save_path] = /var/lib/php/example/session php_value[soap.wsdl_cache_dir] = /var/lib/php/example/wsdlcache # mkdir -p /var/lib/php/example/session # mkdir -p /var/lib/php/example/wsdlcache # chown example:example -R /var/lib/php/example # systemctl restart php-fpm && systemctl enable php-fpm && systemctl status php-fpm
Create nginx virtual host:
# vim /etc/nginx/conf.d/example.conf server { server_name example.com; root /home/example/html; location / { index index.html index.htm index.php; } location ~ \.php$ { include /etc/nginx/fastcgi_params; fastcgi_pass 127.0.0.1:9001; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; } }
Restart and check:
# systemctl restart nginx
Check
To install composer globally follow instructions here: https://getcomposer.org/download/ and then run:
# mv composer.phar /usr/local/bin/composer
Install acme.sh tool: https://github.com/Neilpang/acme.sh
# cd # curl https://get.acme.sh | sh # CTRL+D and reopen terminal
Set letsencrypt as default issuer:
# acme.sh --set-default-ca --server letsencrypt
# acme.sh --issue -d example.com -w /home/example/prod/current/sf/public
Cloudflare API token (https://github.com/acmesh-official/acme.sh/wiki/dnsapi):
Cloudflare -> My profile -> API Tokens -> Create token -> Custom -> Permissions: Zone.Zone Read, Zone.DNS Edit
CF_Account_ID from sidebar on overview page.
CF_Zone_ID from sidebar on zone overview page.
# vim ~/.acme.sh/.example_cf_dns_token # either CF_Account_ID or CF_Zone_ID is sufficient export CF_Account_ID="xxxxxxxxxxxxxxxx" export CF_Zone_ID="yyyyyyyyyyyyyyyy" export CF_Token="zzzzzzzzzzzzzzzzz" # source ~/.acme.sh/.example_cf_dns_token; acme.sh --issue --dns dns_cf -d example.com -d '*.example.com' # crontab -e Update acme.sh cron entry to following: 13 7 * * * /usr/bin/bash -c 'source /root/.acme.sh/.example_cf_dns_token; "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null 2>&1'
# acme.sh --install-cert -d example.com --key-file /etc/pki/tls/private/example.com.key --fullchain-file /etc/pki/tls/certs/example.com.fullchain.crt --reloadcmd "systemctl reload nginx"
Nginx generate strong DHE parameter:
# cd /etc/ssl/certs # openssl dhparam -out dhparam.pem 4096
Nginx config:
server { listen 443 ssl; ... ssl_certificate /etc/pki/tls/certs/example.com.fullchain.crt; ssl_certificate_key /etc/pki/tls/private/example.com.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_dhparam /etc/ssl/certs/dhparam.pem; ... }
Add redirect for notsecure version:
server { listen 80; server_name example.com www.example.com; access_log off; error_log off; root /path/to/webroot; location /.well-known/acme-challenge/ { } location / { return 301 https://$server_name$request_uri; } }
Test website/server on https://www.ssllabs.com/ssltest/index.html (should be A rating) or https://ssldecoder.org/
Taken from: https://serversforhackers.com/c/tcp-load-balancing-with-nginx-ssl-pass-thru