Web server construction with Apache 2.4 (httpd 2.4.43) + PHP 7.4 on Linux ―― 4. Security (chown and firewalld)

Assumptions and preparations

Linux server building article

-Building a file server with Samba (CentOS 8.1 / openSUSE 15.1 / Ubuntu 20.04) -Source compilation of Apache2.4 + PHP7.4 on Linux --1 Apache introduction -Source compilation of Apache2.4 + PHP7.4 on Linux-- 2. PHP introduction -Source compilation of Apache2.4 + PHP7.4 on Linux --3 MySQL introduction --Apache2.4 + PHP7.4 on Linux --4 Security (chown and firewalld) [This article]

Until previous, I built a web application environment with PHP7.4 + MySQL8.0 on Apache2.4, but I have to touch on security as well; ;

With standard Linux firewalld, you only need to specify who uses which port without difficult command rules like iptables or complicated control for each file such as SELinux, and basic security in the firewall. (Of course, it is relatively safe to use security with complicated control even if it is intruded ...)

I also want to use file encryption together, but it will be difficult to talk about, so this time I will only set access rights with firewalld firewall, chown.

Also, in this verification, ** I want to check whether it can be accessed from another network segment, so the Web server will add another network adapter and add another network segment ** (192.168.1.0/24) I am using, but I have added another network adapter (although it is a virtual bridge) to the web server to build 192.168.5.0/24)

environment

--Web server program: Apache 2.4.43 + PHP 7.4.6 + MySQL 8.0 --Client (Main): Windows10 Pro --Client (extension side): Free if it is a GUI OS (Here, I used Windows 10 Italian in use of Insider Preview in Hyper-V (1st generation)) --Server architecture: x64 (operation confirmed with Hyper-V 2nd generation) --Linux distribution: CentOS 8.1 / openSUSE 15.1 Leap / Ubuntu 20.04 (all 64bit)

Premise

--User installed as root (in my verification, it is an administrator account called admin, and it is processed by sudo from there) --For all distributions, the firewall uses firewalld (does not use distribution-specific firewall commands) -Last time article Apache + PHP + MySQL complete Web application server construction itself

Server conditions

IP address

--Client (main): 192.168.1.11 --Client (extension side): 192.168.5.2 --Web server (2 ports): (Main IP) 192.168.1.18, (Extension IP) 192.168.5.1 (Verify with the same IP address for all distributions) --Database server: (integrated with the web server) --Affiliation network segment: (Main) 192.168.1.0/24, (Extension) 192.168.5.0/24 web-from-2-port.png

Ability and version to download and install individual packages (as of June 2020)

Other required packages are installed with the distribution's standard package commands (dnf, apt, etc.) and do not need to be downloaded individually.

For download, you can access the official website, download from there and transfer it by FTP, or you can get it with wget if you know the URL of the download file, but the acquisition method is omitted.

Access control for each network by firewalld

Current state of firewalld

At the time of building the previous itself, I think that the following rules exist in firewalld.

--Port 80 from 192.168.1.0/24 (HTTP): Allowed --Port 443 (HTTPS) from 192.168.1.0/24: Allowed --Other than that, there are some ports such as SSH and Samba that allow different ports, but they are omitted here because they are not related to the Web server.

At this point, even if you add a new network of 192.168.5.0/24 as shown in the "IP address" figure of "Server conditions", you should not be able to access it because the firewall is not open.

Here, to access the web server from the client (192.168.5.2), enter the IP address of the port on the extension side of the web server, https (port is 443): //192.168.5.1/. Of course, it is clear from the network structure that the client on the 192.168.5.0/24 side cannot access the main side (192.168.1.18).

192-168-5-0_443-refuse.png

See (* ॑ ꒳ ॑ *) ⋆ *

Allow / deny access for each network segment with firewalld

Allow access to another network segment

Now, let's add a rule "Port 443 (HTTPS) from 192.168.5.0/24: Allow" to firewalld of the Web server so that it can be allowed even at ** 192.168.5.0/24 **

To identify a network segment and enter a rule to receive a specific port, use firewalld's rich rule. Use --add-rich-rule to enter the rule enclosed in'~'.

# firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.5.0/24" port port="443" protocol="tcp" accept'

This means that the IP family is IPv4, the source is 192.168.5.0/24, port 443, the protocol is TCP, and reception is allowed.

both.png

--Port 80 from 192.168.1.0/24 (HTTP): Allowed --Port 443 (HTTPS) from 192.168.1.0/24: Allowed --Port 443 (HTTPS) from 192.168.5.0/24: Allowed

The screen above is the screen that I tried to access in this firewalld state. You can certainly access it! !! By the way, if you add the option "--permanent" after "firewall-cmd" to make it permanently accessible, the rule will remain applied even if you reboot.

By the way, if you want to remove the permission of port 443 (HTTPS) from the network 192.168.5.0/24, use --remove-rich-rule and put the rule you want to delete inside the'~'. For example, in IPv4, to remove the rules allowed on port 443 (TCP) from 192.168.5.0/24

# firewall-cmd --remove-rich-rule='rule family="ipv4" source address="192.168.5.0/24" port port="443" protocol="tcp" accept'

If you enter, you will not be able to access port 443 (HTTPS) from 192.168.5.0/24.

192-168-5-0_443-refuse.png

To deny network access

Next, I tried this experiment. If you want to deny port 80 (HTTP) on the main network segment 192.168.1.0/24 and leave only port 443 (HTTPS) allowed, then port 80 from IPv4, 192.168.1.0/24 Remove the rule "Allow (TCP)"

# firewall-cmd --remove-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="80" protocol="tcp" accept'

Basically, firewalld blocks anything that does not exist in the rule by default, so if it is not listed in the rule, it will reject reception (whitelist method), so as mentioned above, port 80 of 192.168.1.0/24 If is not in the rule, it will be inaccessible.

port80refuse.png

Apache owner and permission management

Change the Apache startup user

By default in Apache (when the source is compiled and installed), the user is running as a "daemon". Use ps -aux to display a list of all processes and users, and narrow down to those running "httpd", so narrow down with grep httpd.

# ps -aux | grep httpd
root     14249  0.0  0.4 121504 17124 ?        Ss   17:15   0:00 /usr/local/apache2/bin/httpd -k start
daemon   14250  0.0  0.5 1332460 22448 ?       Sl   17:15   0:00 /usr/local/apache2/bin/httpd -k start
daemon   14251  0.0  0.4 1330220 19460 ?       Sl   17:15   0:00 /usr/local/apache2/bin/httpd -k start
daemon   14252  0.0  0.6 1332460 25428 ?       Sl   17:15   0:00 /usr/local/apache2/bin/httpd -k start
admin    17782  0.0  0.0   8176   924 pts/0    S+   18:45   0:00 grep --color=auto httpd

As mentioned above, the user who runs the httpd main unit "/ usr / local / apache2 / bin / httpd" is the default user "daemon".

So, if you have explicitly decided who will run Apache, you can edit httpd.conf to find out how to edit it. For example, if you want to run Apache with user name "apache" and group name "users" (I experimented with openSUSE, the group name is users).

# vi /usr/local/apache2/conf/httpd.conf

httpd.conf


User daemon ← Replace with apache
Group daemon ← Replace with users

So when I restart Apache and use ps -aux again to see who is running httpd,

# ps -aux | grep httpd
root     17985  0.0  0.4 121504 16944 ?        Ss   18:48   0:00 /usr/local/apache2/bin/httpd -k start
apache   17986  0.0  0.3 1327980 16060 ?       Sl   18:48   0:00 /usr/local/apache2/bin/httpd -k start
apache   17987  0.0  0.2 1327980 11980 ?       Sl   18:48   0:00 /usr/local/apache2/bin/httpd -k start
apache   17988  0.0  0.2 1327980 11980 ?       Sl   18:48   0:00 /usr/local/apache2/bin/httpd -k start
admin    18071  0.0  0.0   8176   836 pts/0    S+   18:48   0:00 grep --color=auto httpd

You can see that apache is running httpd properly.

When you want to show files on Apache to others and when you don't want to show them

Now that we've changed the running user of Apache, we want to manage what we see and what we don't want others to see.

If you are another user and do not allow reading

For example, let's assume that the Apache htdocs folder is published on the Web and that the following files exist there.

# cd /usr/local/apache2/htdocs
# ls -l
24 in total
-rw-r--r--1 admin users 304 June 25 17:43 connect.php
-rw-r--r--1 root root 45 June 12 2007 index.html
-rw-r--r--1 root root 20 June 25 17:14 phpi.php
-rw-r--r--1 root root 172 June 25 18:52 some.html
-rw-r--r--1 admin users 346 June 25 17:45 test_form.html
-rw-r--r--1 admin users 1271 June 25 17:45 test_form.php

So let's say you access "some.html". Since the owner is root and the permission is 644, this setting means that anyone can access "some.html", by the way, access with Apache only reads, does not write or execute, so just read I will.

200ok.png

The execution user of Apache is apache. At that time, I was able to read it properly

So I left the owner root and changed the permissions of "some.html" to 600 (make it unreadable by other users and only available to the user).

# chmod 600 some.html
# ls -l
24 in total
-rw-r--r--1 admin users 304 June 25 17:43 connect.php
-rw-r--r--1 root root 45 June 12 2007 index.html
-rw-r--r--1 root root 20 June 25 17:14 phpi.php
-rw-------1 root root 172 June 25 18:52 some.html
-rw-r--r--1 admin users 346 June 25 17:45 test_form.html
-rw-r--r--1 admin users 1271 June 25 17:45 test_form.php

403.png

This time it became Forbidden and could not be read. It's obvious because the Apache execution user apache is prohibited from reading root's.

Files that have the same owner as the Apache execution user and do not allow other users

Now, make "some.html" owned by the Apache execution user, change it so that it cannot be read by other users, and check if it can be accessed again.

# chown apache:users some.html
# ls -l
24 in total
-rw-r--r--1 admin users 304 June 25 17:43 connect.php
-rw-r--r--1 root root 45 June 12 2007 index.html
-rw-r--r--1 root root 20 June 25 17:14 phpi.php
-rw-------1 apache users 172 June 25 18:52 some.html
-rw-r--r--1 admin users 346 June 25 17:45 test_form.html
-rw-r--r--1 admin users 1271 June 25 17:45 test_form.php

200ok.png

This time I was able to access (´ • ̥ ̫ • ̥ `) You can read it because it's your own file

Files that have the same owner as the Apache execution user and do not allow any user

Finally, let's verify with html that no one allows reading Set the "some.html" permission to 000 or 200 and not allow anyone to read

# chmod 200 some.html
# ls -l
24 in total
-rw-r--r--1 admin users 304 June 25 17:43 connect.php
-rw-r--r--1 root root 45 June 12 2007 index.html
-rw-r--r--1 root root 20 June 25 17:14 phpi.php
--w-------1 apache users 172 June 25 18:52 some.html
-rw-r--r--1 admin users 346 June 25 17:45 test_form.html
-rw-r--r--1 admin users 1271 June 25 17:45 test_form.php

403.png

That's right (˙꒳ ˙ᐢ) If you don't allow reading yourself, this will certainly happen ...

Summary

We built the middleware, and the next thing to come is to make arrangements about who allows / denies what, so Qiita should definitely set access rights with firewalld and the owner as a basis. I also wanted to put it here

It seems that encryption is also included in the advanced security field, but if you decide to encrypt the file system, there will be complicated issues regarding password input and key timing, so it is not recommended for beginners ... I thought, so I kept the minimum required encryption in the HTTPS construction method (´ • ̥ ̫ • ̥ `).

Well, the important thing is not to put anything that would be a problem if leaked, not to open unnecessary ports, that is an absolute premise ...

Reference site

-[[CentOS8 / firewall-cmd] Usage and option list ~ Add rules such as rich-rule and configuration file, configuration initialization, meaning of target, definition of service ~](https://milestone-of-se.nesuke. com / sv-basic / linux-basic / firewall-cmd /)

Recommended Posts

Web server construction with Apache 2.4 (httpd 2.4.43) + PHP 7.4 on Linux ―― 4. Security (chown and firewalld)
Source compile Apache2.4 (httpd 2.4.43) + PHP7.4 on Linux and build a Web server ―― 1. Apache introduction
Source compile Apache2.4 (httpd 2.4.43) + PHP7.4 on Linux and build a Web server --2 PHP introduction
Linux Web server construction (Ubuntu & Apache)
Source compile Apache2.4 (httpd 2.4.43) + PHP7.4 on Linux to build a Web server --3 MySQL 8.0 introduction
Effective and simple Web server security measures "Linux"
Source compile Apache2.4 + PHP7.4 with Raspberry Pi and build a Web server --2 PHP introduction
Source compile Apache2.4 + PHP7.4 with Raspberry Pi and build a Web server ―― 1. Apache introduction
Build Apache HTTP Server and Wildfly on Oracle Linux 8
Source compile Apache2.4 + PHP7.4 with Raspberry Pi and build a web server --3. Use MySQL
Environment construction of monitoring server Zabbix 4.4 on CentOS7 (Apache2.4 / PHP5.4 / MariaDB5.5)
Django + Apache with mod_wsgi on Windows Server 2016
Install and Configure TigerVNC server on Linux
Build a CentOS Linux 8 environment with Docker and start Apache HTTP Server
Install Python3 and Django on Amazon Linux (EC2) and run your web server
Launch a web server with Python and Flask
Let's integrate Django and apache (httpd) on Mac! !!
Install PHP 7 series on Amazon Linux 2 with Amazon Linux Extras
Build a server on Linux and local network with Raspberry Pi NextCloud and desktop sharing
Run the flask app on Cloud9 and Apache Httpd
Execute the command on the web server and display the result
Web system construction (super basic) ③: DB server construction and basic operation
Web system construction (super basic) ②: AP server construction and basic operation
[Linux] Create a self-signed certificate with Docker and apache
Web server construction commentary
Ubuntu (18.04.3) Web server construction
Easy web server construction & deployment with EB CLI + git + Django
Set up a web server with CentOS7 + Anaconda + Django + Apache
How to integrate Apache httpd 2.4 and Tomcat 9 on Cent OS 8
Test Python with Miniconda on OS X and Linux with travis-ci
Build Docker environment (Linux 8) and start Apache HTTP Server container
Build a LAMP environment with Vagrant (Linux + Apache + MySQL + PHP)