=======================================
freebsd apache mysql php letsencrypt
=======================================

Example config to setup a web stack to host multiple domains.

- apache
- php
- mysql
- phpmyadmin
- certbot
- logrotate

LAN: 192.168.99.100  dog
WAN: 97.98.99.100    www.example.com

You will want to write some scripts to automate the management of things such as creating and deleting customers as well as their sites.




=======================================
dns server zone record
=======================================

https://www.genunix.com/o1/freebsd_bind9.txt

---------------------------------------

@                       A               97.98.99.100
www                     A               97.98.99.100




=======================================
update the server
=======================================

freebsd-version -kru

freebsd-update fetch

freebsd-update install

shutdown -r now

pkg update

pkg upgrade




=======================================
install apache
=======================================

pkg install apache24


=======================================
/etc/rc.conf
---------------------------------------

# apache
apache24_enable="YES"


=======================================
/usr/local/etc/apache24/httpd.conf
---------------------------------------

LoadModule socache_shmcb_module libexec/apache24/mod_socache_shmcb.so
LoadModule ssl_module libexec/apache24/mod_ssl.so
LoadModule rewrite_module libexec/apache24/mod_rewrite.so
CustomLog "/var/log/httpd-access.log" combined
Include etc/apache24/extra/httpd-autoindex.conf
Include etc/apache24/extra/httpd-default.conf
Include etc/apache24/extra/httpd-ssl.conf
Include etc/apache24/vhosts/*.conf


=======================================
/usr/local/etc/apache24/extra/httpd-default.conf
---------------------------------------

ServerTokens Prod
ServerSignature Off


=======================================
create self signed certificate
---------------------------------------

openssl req -new -x509 -days 36500 -nodes -keyout /usr/local/etc/apache24/server.key -out /usr/local/etc/apache24/server.crt


=======================================
/usr/local/etc/apache24/extra/httpd-ssl.conf
---------------------------------------

Listen 443
SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4:!3DES
SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4:!3DES
SSLHonorCipherOrder on
SSLProtocol all -SSLv3
SSLProxyProtocol all -SSLv3
SSLPassPhraseDialog  builtin
SSLSessionCache        "shmcb:/var/run/ssl_scache(512000)"
SSLSessionCacheTimeout  300
<VirtualHost _default_:443>
DocumentRoot "/usr/local/www/apache24/data"
ServerName 192.168.99.100
ServerAlias 97.98.99.100
ServerAdmin admin@example.com
ErrorLog "/var/log/httpd-error.log"
TransferLog "/var/log/httpd-access.log"
SSLEngine on
SSLCertificateFile "/usr/local/etc/apache24/server.crt"
SSLCertificateKeyFile "/usr/local/etc/apache24/server.key"
<FilesMatch "\.(cgi|shtml|phtml|php)$">
    SSLOptions +StdEnvVars
</FilesMatch>
<Directory "/usr/local/www/apache24/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-5]" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0
CustomLog "/var/log/httpd-ssl_request.log" \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>


=======================================
/usr/local/etc/apache24/vhosts/000.conf
---------------------------------------

# If the server ip address is hit then the FIRST named virtual host will respond therefore we need this to direct it away.
<VirtualHost _default_:80>
  ServerName 192.168.99.100
  ServerAlias 97.98.99.100
  ErrorLog "/var/log/httpd-error.log"
  CustomLog "/var/log/httpd-access.log" combined
  RewriteEngine On
  RewriteCond %{HTTPS} off
  RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L,QSA]
</VirtualHost>

---------------------------------------

mkdir /usr/local/etc/apache24/vhosts

mkdir /usr/local/etc/apache24/auth

touch /usr/local/etc/apache24/auth/passwd

touch /usr/local/etc/apache24/auth/group

apachectl configtest

service apache24 start


=======================================
Confirm it works
---------------------------------------

http://192.168.99.100
https://192.168.99.100

http://97.98.99.100
https://97.98.99.100




=======================================
install php
=======================================

pkg install mod_php84 php84 php84-bcmath php84-brotli php84-bsdconv php84-bz2 php84-calendar php84-ctype php84-curl php84-dba php84-dom php84-enchant php84-exif php84-ffi php84-fileinfo php84-filter php84-gd php84-geos php84-gettext php84-gmp php84-iconv php84-intl php84-ldap php84-lz4 php84-mbstring php84-mysqli php84-odbc php84-opcache php84-pcntl php84-pdo php84-pecl-imagick php84-pecl-pspell php84-phar php84-posix php84-readline php84-session php84-shmop php84-simplexml php84-soap php84-sockets php84-sodium php84-sqlite3 php84-sysvmsg php84-sysvsem php84-sysvshm php84-tidy php84-tokenizer php84-xml php84-xmlreader php84-xmlwriter php84-xsl php84-zip php84-zlib php84-zstd

cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini


=======================================
/usr/local/etc/php.ini
---------------------------------------

expose_php = Off


=======================================
/usr/local/etc/apache24/httpd.conf
---------------------------------------

LoadModule php_module         libexec/apache24/libphp.so
    DirectoryIndex index.php index.html


=======================================
/usr/local/etc/apache24/Includes/php.conf
---------------------------------------

<FilesMatch "\.php$">
  SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch "\.phps$">
  SetHandler application/x-httpd-php-source
</FilesMatch>


=======================================
/usr/local/www/apache24/data/phpinfo.php
---------------------------------------

<?php phpinfo(); ?>

---------------------------------------

apachectl configtest

apachectl restart


=======================================
Confirm it works
---------------------------------------

https://192.168.99.100/phpinfo.php

---------------------------------------

rm /usr/local/www/apache24/data/phpinfo.php

zpool create -f -m /export -o autoexpand=off -O compression=lz4 -O checksum=sha512 -O atime=on tank ada1

zfs create tank/http




=======================================
creating vhosts
=======================================

zfs create tank/http/owner

chown -R root:wheel /export/http/owner

chmod 755 /export/http/owner


=======================================
creating vhost sites
---------------------------------------

zfs create tank/http/owner/www.example.com

chmod 755 /export/http/owner/www.example.com

mkdir "/export/http/owner/www.example.com/logs"

mkdir "/export/http/owner/www.example.com/tmp"

mkdir "/export/http/owner/www.example.com/htdocs"

chown root:wheel "/export/http/owner/www.example.com"

chown root:wheel "/export/http/owner/www.example.com/logs"


=======================================
/export/http/owner/www.example.com/htdocs/index.php
---------------------------------------

Hello World


=======================================
/usr/local/etc/apache24/vhosts/owner.www.example.com.conf
---------------------------------------

<VirtualHost *:80>
  DocumentRoot "/export/http/owner/www.example.com/htdocs"
  ServerName www.example.com
  ServerAlias example.com
  ServerAdmin admin@example.com
  <Directory "/export/http/owner/www.example.com/htdocs">
    Options +FollowSymLinks -Indexes
    AllowOverride All
    Require all granted
  </Directory>
  ErrorLog /export/http/owner/www.example.com/logs/www.example.com-error.log
  CustomLog /export/http/owner/www.example.com/logs/www.example.com-access.log combined
</VirtualHost>

---------------------------------------

apachectl configtest

apachectl restart


=======================================
Confirm it works
---------------------------------------

http://example.com
http://www.example.com




=======================================
install certbot letsencrypt
=======================================

pkg search certbot

pkg install py39-certbot-apache


=======================================
Get certificates
---------------------------------------

certbot --apache certonly


=======================================
Renew certificates by hand
---------------------------------------

certbot renew --dry-run


=======================================
crontab -e
---------------------------------------

@weekly   /usr/local/bin/certbot renew


=======================================
/usr/local/etc/apache24/vhosts/www.example.com.conf
---------------------------------------

<VirtualHost *:80>
  ServerName www.example.com
  ServerAlias example.com
  Redirect / https://www.example.com/
</VirtualHost>

<VirtualHost *:443>
  ServerName www.example.com
  ServerAdmin admin@example.com
  DocumentRoot "/export/http/owner/www.example.com/htdocs"
  <Directory "/export/http/owner/www.example.com/htdocs">
    Options +FollowSymLinks -Indexes
    AllowOverride All
    Require all granted
  </Directory>
  SSLEngine on
  Include /usr/local/etc/letsencrypt/options-ssl-apache.conf
  SSLCertificateFile /usr/local/etc/letsencrypt/live/www.example.com/cert.pem
  SSLCertificateKeyFile /usr/local/etc/letsencrypt/live/www.example.com/privkey.pem
  SSLCertificateChainFile /usr/local/etc/letsencrypt/live/www.example.com/chain.pem
  <FilesMatch "\.(cgi|shtml|phtml|php)$">
    SSLOptions +StdEnvVars
  </FilesMatch>
  BrowserMatch ".*MSIE.*" \
    nokeepalive ssl-unclean-shutdown \
    downgrade-1.0 force-response-1.0
  ErrorLog /export/http/owner/www.example.com/logs/www.example.com-error.log
  CustomLog /export/http/owner/www.example.com/logs/www.example.com-access.log combined
</VirtualHost>

---------------------------------------

apachectl configtest

apachectl restart


=======================================
confirm it works
---------------------------------------

http://example.com
https://example.com
http://www.example.com
https://www.example.com




=======================================
install mariadb (mysql)
=======================================

pkg install mariadb114-server mariadb114-client


=======================================
/etc/rc.conf
---------------------------------------

# mariadb
mysql_enable="YES"
mysql_optfile="/usr/local/etc/mysql/my.cnf"
mysql_dbdir="/export/mysql"


=======================================
/usr/local/etc/mysql/conf.d/server.cnf
---------------------------------------

[mysqld]
datadir                         = /export/mysql
sql_mode                        = ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

---------------------------------------

rm -rf /var/db/mysql

zfs create tank/mysql

chown mysql:mysql /export/mysql

chmod 700 /export/mysql

service mysql-server start

mysql_secure_installation

mysql -u root -p -e "show variables like '%datadir%';"
Enter password:
+---------------+----------------+
| Variable_name | Value          |
+---------------+----------------+
| datadir       | /export/mysql/ |
+---------------+----------------+

mysql -u root -p -e "show variables like '%sql_mode%';"
Enter password:
+---------------+-----------------------------------------------------------------------+
| Variable_name | Value                                                                 |
+---------------+-----------------------------------------------------------------------+
| sql_mode      | ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+-----------------------------------------------------------------------+

mysql -u root -p -e "CREATE USER 'owner'@'localhost' IDENTIFIED VIA mysql_native_password USING '<password>';GRANT USAGE ON *.* TO 'owner'@'localhost' REQUIRE NONE WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;GRANT ALL PRIVILEGES ON `owner\_%`.* TO 'owner'@'localhost';"



=======================================
install phpmyadmin
=======================================

pkg install phpMyAdmin5-php81


=======================================
/usr/local/etc/apache24/Includes/phpmyadmin.conf
---------------------------------------

Alias /myphpmyadminalias "/usr/local/www/phpMyAdmin/"
<Directory "/usr/local/www/phpMyAdmin/">
  Options None
  AllowOverride Limit
  Require ip 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12
</Directory>

---------------------------------------

apachectl configtest

apachectl restart

rm /usr/local/www/phpMyAdmin/config.inc.php


=======================================
phpmyadmin setup
---------------------------------------

https://192.168.99.100/myphpmyadminalias/setup/


=======================================
/usr/local/www/phpMyAdmin/config.inc.php
---------------------------------------

<?php
/**
 * Generated configuration file
 * Generated by: phpMyAdmin 5.2.0 setup script
 * Date: Sun, 12 Feb 2023 05:02:26 +0000
 */

/* Servers configuration */
$i = 0;

/* Server: localhost [1] */
$i++;
$cfg['Servers'][$i]['verbose'] = '';
$cfg['Servers'][$i]['host'] = '';
$cfg['Servers'][$i]['port'] = '';
$cfg['Servers'][$i]['socket'] = '/var/run/mysql/mysql.sock';
$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['user'] = '';
$cfg['Servers'][$i]['password'] = '';

/* End of servers configuration */

$cfg['blowfish_secret'] = '*<T2GaXw}:\\9n6&aqJ#)GP-ki^7X3b$F3';
$cfg['DefaultLang'] = 'en';
$cfg['ServerDefault'] = 1;
$cfg['UploadDir'] = '';
$cfg['SaveDir'] = '';


=======================================
confirm it works
---------------------------------------

https://192.168.99.100/myphpmyadminalias/




=======================================
install logrotate
=======================================

pkg install logrotate


=======================================
/usr/local/etc/logrotate.conf
---------------------------------------

# see "man logrotate" for details
# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# uncomment this if you want your log files compressed
#compress

# RPM packages drop log rotation information into this directory
include /usr/local/etc/logrotate.d

#/var/log/lastlog {
#    monthly
#    rotate 1
#}

# system-specific logs may be configured here


=======================================
/usr/local/etc/logrotate.d/apache24
---------------------------------------

/var/log/httpd-*.log /export/http/*/*/logs/*.log {
  daily
  missingok
  rotate 36500
  dateext
  notifempty
  create 644 root wheel
  sharedscripts
  postrotate
  /usr/local/sbin/apachectl graceful
  endscript
}

---------------------------------------

rm /usr/local/etc/logrotate.d/consolekit

logrotate -d /usr/local/etc/logrotate.conf  <--- dry run

logrotate -f /usr/local/etc/logrotate.conf  <--- force run




=======================================
create vhost sftp users
=======================================

pw useradd -n owner -u 3000 -g www -c "WWW User John Doe" -d /export/http/owner -s /usr/sbin/nologin -C /dev/null


=======================================
/etc/rc.conf
---------------------------------------

syslogd_flags="-s -l /export/http/owner/dev/log"

---------------------------------------

mkdir /export/http/owner/dev

chown owner:www /export/http/owner

service syslogd restart


=======================================
/etc/ssh/sshd_config
---------------------------------------

Match Group www
  PubkeyAuthentication yes
  ChrootDirectory %h
  AllowTcpForwarding no
  X11Forwarding no
  ForceCommand internal-sftp -f AUTH -l INFO

---------------------------------------

service sshd restart




=======================================
setup some protection
=======================================

https://www.genunix.com/o1/freebsd_ipfw.txt

https://www.genunix.com/o1/freebsd_fail2ban.txt




=======================================
done
=======================================