[[https://pctresearch.com/|{{:wiki_banner.jpg?nolink&800|}}]] ===== Ubuntu 24.04 LTS + Apache2 + PHP installarion and setting ===== ^OS|Ubuntu 24.04.2 LTS| ^apache2|2.4.58-1ubuntu8.5| ^PHP|PHP 8.3.6| :!: The PHP and the apache2 version may have changed since this article was written. ==== Installing Apache and Updating the Firewall ==== $ sudo apt update $ sudo apt install apache2 $ sudo ufw app list $ sudo ufw allow in "Apache" $ sudo ufw status ===== Ufw setting ===== ==== OpenSSH ==== $ cat /etc/ufw/applications.d/openssh-server [OpenSSH] title=Secure shell server, an rshd replacement description=OpenSSH is a free implementation of the Secure Shell protocol. ports=22/tcp $ sudo ufw allow 'OpenSSH' $ sudo ufw enable Firewall is active and enabled on system startup $ sudo ufw status Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) If you do not want the sshd to be accessible from outside of your local network, you can do the following: $ sudo ufw delete allow 'OpenSSH' Rule deleted Rule deleted (v6) $ sudo ufw status Status: active $ sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp comment 'Allow ssh from local' Rule added $ sudo ufw status Status: active To Action From -- ------ ---- 22/tcp ALLOW 192.168.1.0/24 # Allow ssh from local ==== Apache2 ==== $ cat /etc/ufw/applications.d/apache2-utils.ufw.profile [Apache] title=Web Server description=Apache v2 is the next generation of the omnipresent Apache web server. ports=80/tcp [Apache Secure] title=Web Server (HTTPS) description=Apache v2 is the next generation of the omnipresent Apache web server. ports=443/tcp [Apache Full] title=Web Server (HTTP,HTTPS) description=Apache v2 is the next generation of the omnipresent Apache web server. ports=80,443/tcp So, you should do one of these three commands. $ sudo ufw app info 'Apache' $ sudo ufw app info 'Apache Secure' $ sudo ufw app info 'Apache Full' Same as the sshd, if you do not want the apache2 to be accessible from outside of your local network, you can do the following: $ sudo ufw delete allow 'Apache' $ sudo ufw delete allow 'Apache Secure' $ sudo ufw delete allow 'Apache Full' $ sudo ufw delete allow 'Apache' $ sudo ufw delete allow 'Apache Secure' $ sudo ufw delete allow 'Apache Full' $ sudo ufw allow from 192.168.1.0/24 to any port 80 proto tcp comment 'Allow http from local' $ sudo ufw allow from 192.168.1.0/24 to any port 443 proto tcp comment 'Allow https from local' ==== enable ufw ==== $ sudo ufw enable Firewall is active and enabled on system startup ==== Set to start ufw on boot ==== $ git diff /etc/ufw/ufw.conf diff --git a/etc/ufw/ufw.conf b/etc/ufw/ufw.conf index 8336b91..28fe534 100644 --- a/etc/ufw/ufw.conf +++ b/etc/ufw/ufw.conf @@ -3,7 +3,7 @@ # Set to yes to start on boot. If setting this remotely, be sure to add a rule # to allow your remote connection before starting ufw. Eg: 'ufw allow 22/tcp' -ENABLED=no +ENABLED=yes # Please use the 'ufw' command to set the loglevel. Eg: 'ufw logging medium'. # See 'man ufw' for details. http://localhost\\ The default Ubuntu 24.04 Apache web page is there for informational and testing purposes. ==== Installing PHP ==== $ sudo apt-get install php libapache2-mod-php $ php --version PHP 8.3.6 (cli) (built: Dec 2 2024 12:36:18) (NTS) Copyright (c) The PHP Group Zend Engine v4.3.6, Copyright (c) Zend Technologies with Zend OPcache v8.3.6, Copyright (c), by Zend Technologies $ apt list 2>/dev/null |grep -e "^php.*installed" php-common/noble,now 2:93ubuntu2 all [installed,automatic] php8.3-cli/noble-updates,noble-security,now 8.3.6-0ubuntu0.24.04.3 amd64 [installed,automatic] php8.3-common/noble-updates,noble-security,now 8.3.6-0ubuntu0.24.04.3 amd64 [installed,automatic] php8.3-opcache/noble-updates,noble-security,now 8.3.6-0ubuntu0.24.04.3 amd64 [installed,automatic] php8.3-readline/noble-updates,noble-security,now 8.3.6-0ubuntu0.24.04.3 amd64 [installed,automatic] php8.3/noble-updates,noble-security,now 8.3.6-0ubuntu0.24.04.3 all [installed,automatic] php/noble,now 2:8.3+93ubuntu2 all [installed] $ sudo apt-get install php-xml # (for Dokuwiki) ==== Create user wweb ==== :!: You can change the user name whatever you want. $ sudo adduser wweb $ sudo usermod -aG sudo wweb $ sudo usermod -aG wweb pctr # replace pctr with your main account's group name ==== Creating a Virtual Host for your Website ==== $ sudo -p mkdir /home/wweb/www/html # instead of (sudo mkdir -p /var/www/your_domain) $ sudo chown -R wweb:wweb /home/wweb/www/html # instead of (sudo chown -R $USER:$USER /var/www/your_domain) $ sudo vim /etc/apache2/sites-available/wweb.conf # instead of (sudo vim /etc/apache2/sites-available/your_domain.conf) ====/etc/apache2/sites-available/your_domain.conf==== ServerName your_domain ServerAlias www.your_domain ServerAdmin webmaster@localhost DocumentRoot /var/www/your_domain ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined :!: ServerAdmin Directive in Apache2 is deprecated. === ServerName Directive === Syntax: ServerName [scheme://]domain-name|ip-address[:port] ex) ServerName www.example.com Or try this. $ cat /etc/hostname ubuntupctr Then ServerName ubuntupctr is enough. ====/etc/apache2/sites-available/wweb.conf==== ServerName ubuntupctr ServerAdmin webmaster@localhost #DocumentRoot /var/www/html DocumentRoot /home/wweb/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined To set the 'ServerName' directive globally in Apache, edit the /etc/apache2/apache2.conf file and add the line ServerName your.server.ip.address or ServerName your.domain.name under the global configuration section. After saving the changes, restart Apache using sudo systemctl restart apache2 to apply the configuration. So, Add a line containing "ex) ServerName 127.0.0.1" to the end of the file: ===/etc/apache2/apache2.conf==== End of file: ServerName ubuntupctr ====/etc/apache2/envvars==== $ cgit diff etc/apache2/envvars diff --git a/etc/apache2/envvars b/etc/apache2/envvars index 708d170..a863276 100644 --- a/etc/apache2/envvars +++ b/etc/apache2/envvars @@ -13,8 +13,8 @@ fi # Since there is no sane way to get the parsed apache2 config in scripts, some # settings are defined via environment variables and then used in apache2ctl, # /etc/init.d/apache2, /etc/logrotate.d/apache2, etc. -export APACHE_RUN_USER=www-data -export APACHE_RUN_GROUP=www-data +export APACHE_RUN_USER=wweb +export APACHE_RUN_GROUP=wweb # temporary state file location. This might be changed to /run in Wheezy+1 export APACHE_PID_FILE=/var/run/apache2$SUFFIX/apache2.pid export APACHE_RUN_DIR=/var/run/apache2$SUFFIX ==== enable your virtual host sites: ==== $ sudo a2ensite wweb.conf Enabling site wweb. To activate the new configuration, you need to run: systemctl reload apache2 disable the default site defined in 000-default.conf $ sudo a2dissite 000-default.conf Site 000-default disabled. To activate the new configuration, you need to run: systemctl reload apache2 Look at the current list of virtual hosts: $ apache2ctl -S VirtualHost configuration: *:80 win11kan (/etc/apache2/sites-enabled/wweb.conf:1) ServerRoot: "/etc/apache2" Main DocumentRoot: "/var/www/html" Main ErrorLog: "/var/log/apache2/error.log" Mutex watchdog-callback: using_defaults Mutex default: dir="/var/run/apache2/" mechanism=default Mutex mpm-accept: using_defaults PidFile: "/var/run/apache2/apache2.pid" Define: DUMP_VHOSTS Define: DUMP_RUN_CFG User: name="wweb" id=1001 not_used Group: name="wweb" id=1001 not_used ==== DirectoryIndex on Apache ==== ====/etc/apache2/mods-enabled/dir.conf==== DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm ====/etc/apache2/apache2.conf==== $ cgit diff /etc/apache2/apache2.conf diff --git a/etc/apache2/apache2.conf b/etc/apache2/apache2.conf index 2410e6d..b943101 100644 --- a/etc/apache2/apache2.conf +++ b/etc/apache2/apache2.conf @@ -167,9 +167,9 @@ Include ports.conf Require all granted - - Options Indexes FollowSymLinks - AllowOverride None + + Options Indexes FollowSymLinks execCGI + AllowOverride All Require all granted ====/etc/apache2/conf-available/serve-cgi-bin.conf==== $ cgit diff /etc/apache2/conf-available/serve-cgi-bin.conf diff --git a/etc/apache2/conf-available/serve-cgi-bin.conf b/etc/apache2/conf-available/serve-cgi-bin.conf index ae660b1..19fa042 100644 --- a/etc/apache2/conf-available/serve-cgi-bin.conf +++ b/etc/apache2/conf-available/serve-cgi-bin.conf @@ -8,8 +8,8 @@ - ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ - + ScriptAlias /cgi-bin/ /home/wweb/www/html/dokuwiki/ + AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Require all granted ====/etc/apache2/sites-available/default-ssl.conf==== # DocumentRoot /var/www/html DocumentRoot /home/wweb/www/html ====configuration test and restart apache2==== test for configuration errors: $ sudo apache2ctl configtest Syntax OK reload Apache so these changes take effect: $ sudo systemctl restart apache2 $ sudo systemctl status apache2 $ sudo systemctl status apache2 ● apache2.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/apache2.service; enabled; preset: enabled) Active: active (running) since Tue 2025-02-25 20:27:32 JST; 5s ago ..... or $ sudo /etc/init.d/apache2 restart $ sudo /etc/init.d/apache2 status ===== Enabling SSL ===== make wweb_ssl.conf from 000-default.conf /etc/apache2/sites-available/wweb_ssl.conf -- ServerAdmin webmaster@localhost DocumentRoot /home/wweb/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine on SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key SSLOptions +StdEnvVars SSLOptions +StdEnvVars -- $ sudo a2ensite wweb_ssl.conf $ sudo a2enmod ssl $ sudo systemctl reload apache2 a2enmod script that enables the specified module within the apache2 configuration. It does this by creating symlinks within /etc/apache2/mods-enabled. a2dismod disables a module by removing those symlinks. If you want to use self-signed certificates, you should install the ssl-cert package (see below). Otherwise, just adjust the SSLCertificateKeyFile and SSLCertificateFile directives in '/etc/apache2/sites-available/default-ssl.conf' to point to your SSL certificate. Then restart apache: $ sudo systemctl restart apache2 ===== Creating self-signed SSL certificates ===== $ apt list --installed 2>/dev/null | grep -i ssl-cert ssl-cert/noble,now 1.1.2ubuntu1 all [installed,automatic] If it isn't installed $ sudo apt install ssl-cert If you install the ssl-cert package, a self-signed certificate will be automatically created using the hostname currently configured on your computer. SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key You can recreate that certificate (e.g. after you have changed '/etc/hosts' or DNS to give the correct hostname) as user root with: $ make-ssl-cert generate-default-snakeoil --force-overwrite To create more certificates with different host names, you can use make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /path/to/cert-file.crt This will ask you for the hostname and place both SSL key and certificate in the file '/path/to/cert-file.crt'. Use this file with the SSLCertificateFile directive in the Apache config (you don't need the SSLCertificateKeyFile in this case as it also contains the key). The file '/path/to/cert-file.crt' should only be readable by root. A good directory to use for the additional certificates/keys is '/etc/ssl/private'. make /usr/share/ssl-cert/ssleay_wweb.cnf from /usr/share/ssl-cert/ssleay.cnf $ sudo cp /usr/share/ssl-cert/ssleay.cnf /usr/share/ssl-cert/ssleay_wweb.cnf $ diff -c /usr/share/ssl-cert/ssleay.cnf /usr/share/ssl-cert/ssleay_wweb.cnf *** /usr/share/ssl-cert/ssleay.cnf 2023-10-01 13:19:41.000000000 +0900 --- /usr/share/ssl-cert/ssleay_wweb.cnf 2025-02-25 22:37:05.706472564 +0900 *************** *** 6,19 **** default_bits = 2048 default_keyfile = privkey.pem distinguished_name = req_distinguished_name prompt = no policy = policy_anything req_extensions = v3_req x509_extensions = v3_req [ req_distinguished_name ] ! commonName = @HostName@ [ v3_req ] basicConstraints = CA:FALSE subjectAltName = @SubjectAltName@ --- 6,27 ---- default_bits = 2048 default_keyfile = privkey.pem distinguished_name = req_distinguished_name + attributes = req_attributes prompt = no policy = policy_anything req_extensions = v3_req x509_extensions = v3_req [ req_distinguished_name ] ! countryName = JP ! commonName = ubuntupctr [ v3_req ] basicConstraints = CA:FALSE subjectAltName = @SubjectAltName@ + + [ req_attributes ] + challengePassword = A challenge password + challengePassword_min = 4 + challengePassword_max = 20 + $ make-ssl-cert [OPTION]... template output-certificate ^--force-overwrite|Always create a new certificate, even if the file already exists. | So, $ sudo make-ssl-cert --force-overwrite /usr/share/ssl-cert/ssleay_wweb.cnf /etc/ssl/private/wweb_cert-file.crt Package configuration ┌─────────────────┤ Configure an SSL Certificate. ├───────────────────────┐ │ Please enter the host name to use in the SSL certificate. │ │ │ │ It will become the 'commonName' field of the generated SSL certificate. │ │ │ │ Host name: │ │ │ │ localhost_______________________________________________________________│ │ │ │ │ └─────────────────────────────────────────────────────────────────────────┘ ┌──────────────────────────────┤ Configure an SSL Certificate. ├────────────────────────────────────────────────┐ │ Please enter any additional names to use in the SSL certificate. │ │ │ │ It will become the 'subjectAltName' field of the generated SSL certificate. │ │ │ │ Multiple alternative names should be delimited with comma and no spaces. For a web server with multiple DNS │ │ names this could look like: │ │ │ │ DNS:www.example.com,DNS:images.example.com │ │ │ │ A more complex example including a hostname, a WebID, an email address, and an IPv4 address: │ │ │ │ DNS:example.com,URI:http://example.com/joe#me,email:me@example.com,IP:192.168.7.3 │ │ │ │ Alternative name(s): │ │ │ │ DNS:ubuntupctr,URI:ubuntupctr,email:your_mail@address.com,IP:192.168.1.2_____________________________________ │ │ │ │ │ │ │ └───────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ $ sudo ll /etc/ssl/private/ | grep wweb_cert-file.crt lrwxrwxrwx 1 root root 18 Feb 25 23:23 9ae71ddb.0 -> wweb_cert-file.crt -rw------- 1 root root 2896 Feb 25 23:23 wweb_cert-file.crt For reference, Invoked with "generate-default-snakeoil": $ make-ssl-cert generate-default-snakeoil --force-overwrite will generate: /etc/ssl/certs/ssl-cert-snakeoil.pem and /etc/ssl/private/ssl-cert-snakeoil.key. 'openssl req' command primarily creates and processes certificate requests (CSRs) in PKCS#10 format. It can additionally create self-signed certificates for use as root CAs for example. $ sudo openssl req -new -newkey rsa:2048 -nodes -keyout wweb_server.key -out wweb_server.csr ......+....+.....+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+.+..+.+..+....+.....+.+..+............................+.....+....+.....+....+..+....+.........+.....+....+.....+............+.+..+.+..+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ..+........+.......+......+.....+..........+..+.+..+.........+....+..+...+.......+..+.+.....+.+...+...+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+...+...+..............+.+.....+.........+...+....+...+.....+.......+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*....+......+........+......+...................+..+.............+.................+.........+...+.......+.....+...+.+..+...+.+.....+.+........+..........+.....+....+..+....+......+...........+.......+.....+.+..+..........+.........+........+.............+..+..........+..+.+...+..+............+...+....+.....+...+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:JP State or Province Name (full name) [Some-State]:Tokyo Locality Name (eg, city) []:Shinjuku-ku Organization Name (eg, company) [Internet Widgits Pty Ltd]:PCTResearch Organizational Unit Name (eg, section) []:Security Common Name (e.g. server FQDN or YOUR name) []:ubuntupctr Email Address []:your_mail@address.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:******** An optional company name []: $ sudo mv wweb_server.key /etc/ssl/private/ $ sudo openssl x509 -req -signkey /etc/ssl/private/wweb_server.key -in wweb_server.csr -out wweb_server.crt Certificate request self-signature ok subject=C = JP, ST = Tokyo, L = Shinjuku-ku, O = PCTResearch, OU = Security, CN = ubuntupctr, emailAddress = your_mail@address.com $ sudo mv wweb_server.csr wweb_server.crt /etc/ssl/certs/ $ sudo ls -la /etc/ssl/private/ | grep wweb lrwxrwxrwx 1 root root 18 Feb 25 23:23 9ae71ddb.0 -> wweb_cert-file.crt -rw------- 1 root root 2896 Feb 25 23:23 wweb_cert-file.crt -rw------- 1 root root 1708 Feb 25 23:36 wweb_server.key $ ll /etc/ssl/certs | grep wweb -rw-r--r-- 1 root root 1342 Feb 25 23:44 wweb_server.crt -rw-r--r-- 1 root root 1106 Feb 25 23:41 wweb_server.csr The following sections are for reference. ==== How to create a self-signed PEM file ==== Privacy Enhanced Mail (PEM) files are concatenated certificate containers frequently used in certificate installations when multiple certificates that form a complete chain are being imported as a single file. They are a defined standard in RFCs 1421 through 1424. They can be thought of as a layered container of chained certificates. A .pem file is a container format that may just include the public certificate or the entire certificate chain (private key, public key, root certificates): Private Key Server Certificate (crt, puplic key) (optional) Intermediate CA and/or bundles if signed by a 3rd party $ sudo openssl req -new -x509 -days 3650 -nodes -newkey rsa:2048 -keyout key.pem -out cert.pem ==== How to create a PEM file from existing certificate files that form a chain ==== (optional) Remove the password from the Private Key by following the steps listed below: $ openssl rsa -in server.key -out nopassword.key Note: Enter the pass phrase of the Private Key. Combine the private key, public certificate and any 3rd party intermediate certificate files: $ cat nopassword.key > server.pem $ cat server.crt >> server.pem Note: Repeat this step as needed for third-party certificate chain files, bundles, etc: cat intermediate.crt >> server.pem ==== logs of apache2 ==== /etc/apache2/envvars export APACHE_LOG_DIR=/var/log/apache2$SUFFIX /etc/apache2/sites-available/wweb.conf ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined /var/log/apache2/ access.log error.log