One place for hosting & domains

      FreeBSD

      How To Configure Packet Filter (PF) on FreeBSD 12.1


      The author selected the COVID-19 Relief Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      The firewall is arguably one of the most important lines of defense against cyber attacks. The ability to configure a firewall from scratch is an empowering skill that enables the administrator to take control of their networks.

      Packet Filter (PF) is a renown firewall application that is maintained upstream by the security-driven OpenBSD project. It is more accurately expressed as a packet filtering tool, hence the name, and it is known for its simple syntax, user-friendliness, and extensive features. PF is a stateful firewall by default, storing information about connections in a state table that can be accessed for analytical purposes. PF is part of the FreeBSD base system and is supported by a strong community of developers. Although there are differences between the FreeBSD and OpenBSD versions of PF related to kernel architectures, in general their syntax is similar. Depending on their complexity, common rulesets can be modified to work on either distribution with relatively little effort.

      In this tutorial you’ll build a firewall from the ground up on a FreeBSD 12.1 server with PF. You’ll design a base ruleset that can be used as a template for future projects. You’ll also explore some of PF’s advanced features such as packet hygiene, brute force prevention, monitoring and logging, and other third-party tools.

      Prerequisites

      Before you start this tutorial, you’ll need the following:

      • A 1G FreeBSD 12.1 server (either ZFS or UFS). You can use our How To Get Started with FreeBSD tutorial to set your server up to your preferred configuration.
      • FreeBSD has no firewall enabled by default—customization is a hallmark of the FreeBSD ethos. Therefore when you first launch your server, you need temporary protection while PF is being configured. If you’re using DigitalOcean, you can enable your cloud firewall immediately after spinning up the server. Refer to DigitalOcean’s Firewall Quickstart for instructions on configuring a cloud firewall. If you’re using another cloud provider, determine the fastest route to immediate protection before you begin. Whichever method you choose, your temporary firewall must permit only inbound SSH traffic, and can allow all types of outbound traffic.

      Step 1 — Building Your Preliminary Ruleset

      You’ll begin this tutorial by drafting a preliminary ruleset that provides basic protection and access to critical services from the internet. At this point you have a running FreeBSD 12.1 server with an active cloud firewall.

      There are two approaches to building a firewall: default deny and default permit. The default deny approach blocks all traffic, and only permits what is specified in a rule. The default permit approach does the exact opposite: it passes all traffic, and only blocks what is specified in a rule. You’ll use the default deny approach.

      PF rulesets are written in a configuration file named /etc/pf.conf, which is also its default location. It is OK to store this file somewhere else as long as it is specified in the /etc/rc.conf configuration file. In this tutorial you’ll use the default location.

      Log in to your server with your non-root user:

      • ssh freebsd@your_server_ip

      Next create your /etc/pf.conf file:

      Note: If you would like to see the complete base ruleset at any point in the tutorial, you can refer to the examples in Step 4 or Step 8.

      PF filters packets according to three core actions: block, pass, and match. When combined with other options they form rules. An action is taken when a packet meets the criteria specified in a rule. As you may expect, pass and block rules will pass and block traffic. A match rule performs an action on a packet when it finds a matching criteria, but doesn’t pass or block it. For example, you can perform network address translation (NAT) on a matching packet without passing or blocking it, and it will sit there until you tell it to do something in another rule, such as route it to another machine or gateway.

      Next add the first rule to your /etc/pf.conf file:

      /etc/pf.conf

      block all
      

      This rule blocks all forms of traffic in every direction. Since it does not specify a direction, it defaults to both in and out. This rule is legitimate for a local workstation that needs to be insulated from the world, but it is largely impractical, and will not work on a remote server because it does not permit SSH traffic. In fact, had you enabled PF, you would have locked yourself out of the server.

      Revise your /etc/pf.conf file to allow SSH traffic with the following highlighted line:

      /etc/pf.conf

      block all
      pass in proto tcp to port 22
      

      Note: Alternatively, you can use the name of the protocol:

      /etc/pf.conf

      block all
      pass in proto tcp to port ssh
      

      For the sake of consistency we will use port numbers, unless there is a valid reason not to. There is a detailed list of protocols and their respective port numbers in the /etc/services file, which you are encouraged to view.

      PF processes rules sequentially from top-to-bottom, therefore your current ruleset initially blocks all traffic, but then passes it if the criteria on the next line is matched, which in this case is SSH traffic.

      You can now SSH in to your server, but you’re still blocking all forms of outbound traffic. This is problematic because you can’t access critical services from the internet to install packages, update your time settings, and so on.

      To address this, append the following highlighted rule to the end of your /etc/pf.conf file:

      /etc/pf.conf

      block all
      pass in proto tcp to port { 22 }
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      

      Your ruleset now permits outbound SSH, DNS, HTTP, NTP, and HTTPS traffic, as well as blocking all inward traffic, (with the exception of SSH). You place the port numbers and protocols inside curly brackets, which forms a list in PF syntax, allowing you to add more port numbers if needed. You also add a pass out rule for the UDP protocol on ports 53 and 123 because DNS and NTP often toggle between both the TCP and UDP protocols. You’re almost finished with the preliminary ruleset, and only need to add a couple of rules to achieve basic functionality.

      Complete the preliminary ruleset with the highlighted rules:

      Preliminary Ruleset /etc/pf.conf

      set skip on lo0
      block all
      pass in proto tcp to port { 22 }
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass out inet proto icmp icmp-type { echoreq }
      

      Save and exit the file.

      You create a set skip rule for the loopback device because it does not need to filter traffic and would likely bring your server to a crawl. You add a pass out inet rule for the ICMP protocol, which allows you to use the ping(8) utility for troubleshooting. The inet option represents the IPv4 address family.

      ICMP is a multi-purpose messaging protocol used by networking devices for various types of communication. The ping utility for example uses a type of message known as an echo request, which you’ve added to your icmp_type list. As a precaution, you only permit the message types that you need to prevent unwelcome devices from contacting your server. As your needs increase you can add more message types to your list.

      You now have a working ruleset that provides basic functionality to most machines. In the next section, let’s confirm that everything is working correctly by enabling PF and testing your preliminary ruleset.

      Step 2 — Testing Your Preliminary Ruleset

      In this step you’ll test your preliminary ruleset and make the transition from your cloud firewall to your PF firewall, allowing PF to completely take over. You’ll activate your ruleset with the pfctl utility, which is PF’s built-in command-line tool, and the primary method of interfacing with PF.

      PF rulesets are nothing more than text files, which means there are no delicate procedures involved with loading new rulesets. You can load a new ruleset, and the old one is gone. There is rarely, if ever, a need to flush an existing ruleset.

      FreeBSD uses a web of shell scripts known as the rc system to manage how services are started at boot-time; we specify those services in various rc configuration files. For global services such as PF, you use the /etc/rc.conf file. Since rc files are critical to the well being of a FreeBSD system, they should not be edited directly. Instead FreeBSD provides a command-line utility known as sysrc designed to help you edit these files safely.

      Let’s enable PF using the sysrc command-line utility:

      • sudo sysrc pf_enable="YES"
      • sudo sysrc pflog_enable="YES"

      Verify these changes by printing the contents of your /etc/rc.conf file:

      You will see the following output:

      Output

      pf_enable="YES" pflog_enable="YES"

      You also enable the pflog service, which in turn, enables the pflogd daemon for logging in PF.(You’ll work with logging in a later step.

      You specify two global services in your /etc/rc.conf file, but they won’t initialize until you reboot the server or start them manually. Reboot the server so that you can also test your SSH access.

      Start PF by rebooting the server:

      The connection will be dropped. Give it a few minutes to update.

      Now SSH back in to the server:

      • ssh freebsd@your_server_ip

      Although you’ve initialized your PF services, you haven’t actually loaded your /etc/pf.conf ruleset, which means your firewall is not yet active.

      Load the ruleset with pfctl:

      • sudo pfctl -f /etc/pf.conf

      If there are no errors or messages, it means your ruleset has no errors and the firewall is active.

      Now that PF is running, you can detach your server from your cloud firewall. This can be accomplished at the control panel in your DigitalOcean account by removing your Droplet from your cloud firewall’s portal. If you’re using another cloud provider, ensure that whatever you are using for temporary protection is disabled. Running two different firewalls on a server will almost certainly cause problems.

      For good measure, reboot your server again:

      After a few minutes, SSH back in to your server:

      • ssh freebsd@your_server_ip

      PF is now your acting firewall. You can ensure that it is running by accessing some data with the pfctl utility.

      Let’s view some statistics and counters with pfctl -si:

      You pass the -si flags, which stand for show info. This is one of the many filter parameter combinations you can use with pfctl to parse data about your firewall activity.

      You will see the following tabular data (the values will vary from machine-to-machine):

      Output

      Status: Enabled for 0 days 00:01:53 Debug: Urgent State Table Total Rate current entries 5 searches 144 1.3/s inserts 11 0.1/s removals 6 0.1/s Counters match 23 0.2/s bad-offset 0 0.0/s fragment 0 0.0/s short 0 0.0/s normalize 0 0.0/s memory 0 0.0/s bad-timestamp 0 0.0/s congestion 0 0.0/s ip-option 0 0.0/s proto-cksum 0 0.0/s state-insert 0 0.0/s state-limit 0 0.0/s src-limit 0 0.0/s synproxy 0 0.0/s map-failed 0 0.0/s

      Since you just activated your ruleset, you won’t see a lot of information yet. However this output shows that PF already recorded 23 matched rules, meaning that the criteria of your ruleset was matched 23 times. The output also confirms that your firewall is working.

      Your ruleset also permits outbound traffic to access some critical services from the internet, including the ping utility.

      Let’s check for internet connectivity and DNS service with ping against google.com:

      Since you ran the count flag -c 3, you’ll see three successful connection responses:

      Output

      PING google.com (172.217.0.46): 56 data bytes 64 bytes from 172.217.0.46: icmp_seq=0 ttl=56 time=2.088 ms 64 bytes from 172.217.0.46: icmp_seq=1 ttl=56 time=1.469 ms 64 bytes from 172.217.0.46: icmp_seq=2 ttl=56 time=1.466 ms --- google.com ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 1.466/1.674/2.088/0.293 ms

      Ensure that you can access the the pkgs repository with the following command:

      If there are any packages to upgrade, go ahead and upgrade them.

      If both of these services are working, it means your firewall is working and you can now proceed. Although your preliminary ruleset provides protection and functionality, it is still an elementary ruleset, and could use some enhancements. In the remaining sections you’ll complete your base ruleset, and use some of PF’s advanced features.

      Step 3 — Completing Your Base Ruleset

      In this step you’ll build off of the preliminary ruleset to complete your base ruleset. You’ll reorganize some of your rules and work with more advanced concepts.

      Incorporating Macros and Tables

      In your preliminary ruleset you hard coded all of your parameters into each rule, that is, the port numbers that make up the lists. This may become unmanageable in the future, depending on the nature of your networks. For organizational purposes PF includes macros, lists, and tables. You’ve already included lists directly in your rules, but you can also separate them from your rules and assign them to a variable using macros.

      Open your file to transfer some of your parameters into macros:

      Now add the following content to the very top of the ruleset:

      /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq }"
      . . .
      

      Modify your previous SSH and ICMP rules with your new variables:

      /etc/pf.conf

      . . .
      pass in on $vtnet0 proto tcp to port { 22 }
      . . .
      pass inet proto icmp icmp-type $icmp_types
      . . .
      

      Your previous SSH and ICMP rules now use macros. The variable names are denoted by PF’s dollar sign syntax. You assign your vtnet0 interface to a variable with the same name just as a formality, which gives you the option to rename it in the future if needed. Other common variable names for public facing interfaces include $pub_if or $ext_if.

      Next you’ll implement a table, which is similar to a macro, but designed to hold groups of IP addresses. Let’s create a table for non-routable IP addresses, which often play a role in denial of service attacks (DOS). You can use the IP addresses specified in RFC6890, which defines special-purpose IP address registries. Your server should not send or receive packets to or from these addresses via the public facing interface.

      Create this table by adding the following content directly under the icmp_types macro:

      /etc/pf.conf

      . . .
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      . . .
      

      Now add your rules for the <rfc6890> table underneath the set skip on lo0 rule:

      /etc/pf.conf

      . . .
      set skip on lo0
      block in quick on egress from <rfc6890>
      block return out quick on egress to <rfc6890>
      . . .
      

      Here you introduce the return option, which complements your block out rule. This will drop the packets and also send an RST message to the host that tried to make those connections, which is useful for analyzing host activity. Then, you add the egress keyword, which automatically finds the default route(s) on any given interface(s). This is typically a cleaner method of finding default routes, especially with complex networks. The quick keyword executes rules immediately without considering the rest of the ruleset. For example, if a packet with an illogical IP addresses tries to connect to the server, you want to drop the connection immediately, and have no reason to run that packet through the remainder of the ruleset.

      Protecting Your SSH Ports

      Since your SSH port is open to the public, it is subject to exploitation. One of the more obvious warning signs of an attacker is mass quantities of log-in attempts. For example if the same IP address tries to log in to your server ten times in one second, you can assume that it was not done with human hands, but with computer software that was trying to crack your login password. These types of systematic exploits are often referred to as brute force attacks, and usually succeed if the server has weak passwords.

      Warning: We strongly recommend using public-key authentication on all servers. Refer to DigitalOcean’s tutorial on key-based authentication.

      PF has built-in features for handling brute force and other similar attacks. With PF you can limit the number of simultaneous connection attempts allowed by a single host. If a host exceeds those limits, the connection will be dropped, and they will be banned from the server. To accomplish this you’ll use PF’s overload mechanism, which maintains a table of banned IP addresses.

      Modify your previous SSH rule to limit the number of simultaneous connections from a single host as per the following:

      /etc/pf.conf

      . . .
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      . . .
      

      You add the keep state option that allows you to define the state criteria for the overload table. You pass the max-src-conn parameter to specify the number of simultaneous connections allowed from a single host per second, and the max-src-conn-rate parameter to specify the number of new connections allowed from a single host per second. You specify 15 connections for max-src-conn, and 3 connections for max-src-conn-rate. If these limits are exceeded by a host, the overload mechanism adds the source IP to the <bruteforce> table, which bans them from the server. Finally, the flush global option immediately drops the connection.

      You’ve defined an overload table in your SSH rule, but haven’t declared that table in your ruleset.

      Add the <bruteforce> table underneath the icmp_types macro:

      /etc/pf.conf

      . . .
      icmp_types = "{ echoreq }"
      table <bruteforce> persist
      . . .
      

      The persist keyword allows an empty table to exist in the ruleset. Without it, PF will complain that there are no IP addresses in the table.

      These measures ensure that your SSH port is protected by a powerful security mechanism. PF allows you to configure quick solutions to protect from disastrous forms of exploitation. In the next sections you’ll take steps to clean up packets as they arrive at your server.

      Sanitizing Your Traffic

      Note: The following sections describe basic fundamentals of the TCP/IP protocol suite. If you plan on building web applications or networks, it is in your best interest to master these concepts. Have a look at DigitalOcean’s Introduction to Networking Terminology, Interfaces, and Protocols tutorial.

      Due to the complexity of the TCP/IP protocol suite, and the perserverance of malicious actors, packets often arrive with discrepancies and ambiguities such as overlapping IP fragments, phony IP addresses, and more. It is imperative that you sanitize your traffic before it enters the system. The technical term for this process is normalization.

      When data travels through the internet, it is typically broken up into smaller fragments at its source to accommodate for the transmission parameters of the target host, where it is reassembled into complete packets. Unfortunately an intruder can hijack this process in a number of ways that span beyond the scope of this tutorial. However, with PF you can manage fragmentation with one rule. PF includes a scrub keyword that normalizes packets.

      Add the scrub keyword directly preceding your block all rule:

      /etc/pf.conf

      . . .
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      block all
      . . .
      

      This rule applies scrubbing to all incoming traffic. You include the fragment reassemble option that prevents fragments from entering the system. Instead they are cached in memory until they are reassembled into complete packets, which means your filter rules will only have to contend with uniform packets. You also include the max-mss 1440 option, which represents the maximum segment size of reassembled TCP packets, also known as the payload. You specify a value of 1440 bytes, which strikes a balance between size and performance, leaving plenty of room for the headers.

      Another important aspect of fragmentation is a term known as the maximum transmission unit (MTU). The TCP/IP protocols enable devices to negotiate packet sizes for making connections. The target host uses ICMP messages to inform the source IP of its MTU, a process known as MTU path discovery. The specific ICMP message type is the destination unreachable. You’ll enable MTU path discovery by adding the unreach message type to your icmp_types list.

      You’ll use your server’s default MTU of 1500 bytes, which can be determined with the ifconfig command:

      You will see the following output that includes your current MTU:

      Output

      vtnet0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=6c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6> . . .

      Update the icmp_types list to include the destination unreachable message type:

      /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach}"
      . . .
      

      Now that you have policies in place to handle fragmentation, the packets that enter your system will be uniform and consistent. This is desirable because there are so many devices exchanging data over the internet.

      You’ll now work to prevent another security concern known as IP spoofing. Attackers often change their source IPs to make it appear as if they reside on a trusted node within an organization. PF includes an antispoofing directive for handling spoofed source IPs. When applied to a specific interface(s), antispoofing blocks all traffic from the network of that interface (unless it originates from that interface). For example, if you apply antispoofing to an interface(s) that resides at 5.5.5.1/24, all traffic from the 5.5.5.0/24 network cannot communicate with the system unless it originates from that interface(s).

      Add the following highlighted content to apply antispoofing to your vtnet0 interface:

      /etc/pf.conf

      . . .
      set skip on lo0
      scrub in
      antispoof quick for $vtnet0
      block all
      . . .
      

      Save and exit the file.

      This antispoofing rule says that all traffic from vtnet0’s network(s) can only pass through the vtnet0 interface, or it will be dropped immediately with the quick keyword. Bad actors will not be able to hide in vtnet0’s network and communicate with other nodes.

      To demonstrate your antispoofing rule, you’ll print your ruleset to the screen in its verbose form. Rules in PF are typically written in a shortened form, but they can also be written in a verbose form. It is generally impractical to write rules this way, but for testing purposes it can be useful.

      Print the contents of /etc/pf.conf using pfctl with the following command:

      • sudo pfctl -nvf /etc/pf.conf

      This pfctl command takes the -nvf flags, which print the ruleset and test it without actually loading anything, also known as a dry run. You will now see the entire contents of /etc/pf.conf in its verbose form.

      You’ll see something similar to the following output within the antispoofing portion:

      Output

      . . . block drop in quick on ! vtnet0 inet from your_server_ip/20 to any block drop in quick on ! vtnet0 inet from network_address/16 to any block drop in quick inet from your_server_ip to any block drop in quick inet from network_address to any block drop in quick on vtnet0 inet6 from your_IPv6_address to any . . .

      Your antispoofing rule discovered that it is part of the your_server_ip/20 network. It also detected that (for this tutorial’s example) the server is part of a network_address/16 network, and has an additional IPv6 address. Antispoofing blocks all of these networks from communicating with the system, unless their traffic passes through the vtnet0 interface.

      Your antispoofing rule is the last addition to your base ruleset. In the next step you’ll initiate these changes and perform some testing.

      Step 4 — Testing Your Base Ruleset

      In this step you’ll review and test your base ruleset to ensure that everything is functioning properly. It’s best to avoid implementing too many rules at once without testing them. Best practice is to start with the essentials, expand incrementally, and back work up while making configuration changes.

      Here is your complete base ruleset:

      Base Ruleset /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach }"
      table <bruteforce> persist
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      antispoof quick for $vtnet0
      block in quick on $vtnet0 from <rfc6890>
      block return out quick on egress to <rfc6890>
      block all
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass inet proto icmp icmp-type $icmp_types
      

      Be sure that your /etc/pf.conf file is identical to the complete base ruleset here before continuing. Then save and exit the file.

      Your complete base ruleset provides you with:

      • A collection of macros that can define key services and devices.
      • Network hygiene policies to address packet fragmentation and illogical IP addresses.
      • A default deny filtering structure that blocks everything and permits only what you specify.
      • Inbound SSH access with limits on the number of simultaneous connections that can be made by a host.
      • Outbound traffic policies that give you access to some critical services from the internet.
      • ICMP policies that provide access to the ping utility and MTU path discovery.

      Run the following pfctl command to take a dry run:

      • sudo pfctl -nf /etc/pf.conf

      You pass the -nf flags that tell pfctl to run the ruleset without loading it, which will throw errors if anything is wrong.

      Now, with no encountered errors, load the ruleset:

      • sudo pfctl -f /etc/pf.conf

      If there are no errors, it means your base ruleset is active and functioning properly. As earlier in the tutorial, you’ll perform a few tests on your ruleset.

      First test for internet connectivity and DNS service:

      You will see the following output:

      Output

      PING google.com (172.217.0.46): 56 data bytes 64 bytes from 172.217.0.46: icmp_seq=0 ttl=56 time=2.088 ms 64 bytes from 172.217.0.46: icmp_seq=1 ttl=56 time=1.469 ms 64 bytes from 172.217.0.46: icmp_seq=2 ttl=56 time=1.466 ms --- google.com ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 1.466/1.674/2.088/0.293 ms

      Then, check that you reach the pkgs repository:

      Once again, upgrade packages if it’s needed.

      Finally, reboot your server:

      Give your server a few minutes to reboot. You’ve completed and implemented your base ruleset, which is a significant step in terms of your progress. You’re now ready to explore some of PF’s advanced features. In the next step you will continue to prevent brute force attacks.

      Step 5 — Managing Your Overload Table

      Over time the <bruteforce> overload table will become full of malicious IP addresses and will need to be cleared periodically. It is unlikely that an attacker will continue using the same IP address, so it is counterintuitive to store them in the overload table for long periods of time.

      You’ll use pfctl to manually clear IP addresses that have been stored in the overload table for 48 hours or more with the following command:

      • sudo pfctl -t bruteforce -T expire 172800

      You will see output similar to:

      Output

      0/0 addresses expired.

      You pass the -t bruteforce flag, which stands for table bruteforce, and the -T flag, which lets you run a handful of built-in commands. In this case you run the expire command to clear all entries from -t bruteforce with a time value represented in seconds. Since you’re working on a fresh server, there are probably no IP addresses in the overload table yet.

      This rule works for quick fixes, but a more robust solution would be to automate the process with cron, FreeBSD’s job scheduler. Let’s create a shell script that runs this command sequence instead.

      Create a shell script file in the /usr/local/bin directory:

      • sudo vi /usr/local/bin/clear_overload.sh

      Add the following content to the shell script:

      /usr/local/bin/clear_overload.sh

      #!/bin/sh
      
      pfctl -t bruteforce -T expire 172800
      

      Make the file executable with the following command:

      • sudo chmod 755 /usr/local/bin/clear_overload.sh

      Next you’ll create a cron job. These are jobs that will run repetitively according to a time that you specify. They are commonly used for backups, or any process that needs to run at the same time every day. You create cron jobs with crontab files. Please refer to the man pages to learn more about cron(8) and crontab(5).

      Create a root user crontab file with the following command:

      Now add the following contents to the crontab file:

      crontab

      # minute    hour    mday    month   wday    command
      
        *             0     *       *     *     /usr/local/bin/clear_overload.sh
      

      Save and exit the file.

      Note: Please align every value to its corresponding table entry for readability if things do not align properly when you add the content.

      This cron job runs the clear_overload.sh script every day at midnight, removing IP addresses that are 48 hours old from the overload table <bruteforce>. Next you’ll add anchors to your ruleset.

      Step 6 — Introducing Anchors to Your Rulesets

      In this step you’ll introduce anchors, which are used for sourcing rules into the main ruleset, either manually or from an external text file. Anchors can contain rule snippets, tables, and even other anchors, known as nested anchors. Let’s demonstrate how anchors work by adding a table to an external file, and sourcing it into your base ruleset. Your table will include a group of internal hosts that you want to prevent from connecting to the outside world.

      Create a file named /etc/blocked-hosts-anchor:

      • sudo vi /etc/blocked-hosts-anchor

      Add the following contents to the file:

      /etc/blocked-hosts-anchor

      table <blocked-hosts> { 192.168.47.1 192.168.47.2 192.168.47.3 }
      
      block return out quick on egress from <blocked-hosts>
      

      Save and exit the file.

      These rules declare and define the <blocked-hosts> table, and then prevent every IP address in the <blocked-hosts> table from accessing services from the outside world. You use the egress keyword as a preferred method of finding the default route, or way out, to the internet.

      You still need to declare the anchor in your /etc/pf.conf file:

      Now add the following anchor rules after the block all rule:

      /etc/pf.conf

      . . .
      block all
      anchor blocked_hosts
      load anchor blocked_hosts from "/etc/blocked-hosts-anchor"
      . . .
      

      Save and exit the file.

      These rules declare the blocked_hosts and load the anchor rules into your main ruleset from the /etc/blocked-hosts-anchor file.

      Now initiate these changes by reloading your ruleset with pfctl:

      • sudo pfctl -f /etc/pf.conf

      If there are no errors, it means that there are no errors in your ruleset and your changes are active.

      Use pfctl to verify that your anchor is running:

      The -s Anchors flag stands for “show anchors”. You’ll see the following output:

      Output

      blocked_hosts

      The pfctl utility can also parse the specific rules of your anchor with the -a and -s flags:

      • sudo pfctl -a blocked_hosts -s rules

      You will see the following output:

      Output

      block return out quick on egress from <blocked-hosts> to any

      Another feature of anchors is that they allow you to add rules on-demand without having to reload the ruleset. This can be useful for testing, quick-fixes, emergencies, and so on. For example if an internal host is acting peculiar and you want to block it from making outward connections, you can have an anchor in place that allows you to intervene quickly from the command line.

      Let’s open /etc/pf.conf and add another anchor:

      You’ll name the anchor rogue_hosts, and place it in the block all rule:

      /etc/pf.conf

      . . .
      block all
      anchor rogue_hosts
      . . .
      

      Save and exit the file.

      To initiate these changes, reload the ruleset with pfctl:

      • sudo pfctl -f /etc/pf.conf

      Once again, use pfctl to verify that the anchor is running:

      This will generate the following output:

      Output

      blocked_hosts rogue_hosts

      Now that the anchor is running, you can add rules to it at anytime. Test this by adding the following rule:

      • sudo sh -c 'echo "block return out quick on egress from 192.168.47.4" | pfctl -a rogue_hosts -f -'

      This invokes the echo command and its string content, which is then piped into the pfctl utility with the | symbol, where it is processed into an anchor rule. You open another shell session with the sh -c command. This is because you establish a pipe between two processes, but need sudo privileges to persist throughout the entire command sequence. There are multiple ways of resolving this; here you open an additional shell process with sudo privileges using sudo sh -c.

      Now, use pfctl again to verify that these rules are active:

      • sudo pfctl -a rogue_hosts -s rules

      This will generate the following output:

      Output

      block return out quick on egress inet from 192.168.47.4 to any

      The use of anchors is completely situational and often subjective. Like any other feature there are pros and cons to using anchors. Some applications such as blacklistd interface with anchors by design. Next you’ll focus on logging with PF, which is a critical aspect of network security. Your firewall is not useful if you can’t see what it is doing.

      Step 7 — Logging Your Firewall’s Activity

      In this step you’ll work with PF logging, which is managed by a pseudo-interface named pflog. Logging is enabled at boot-time by adding pflog_enabled=YES to the /etc/rc.conf file, which you did in Step 2. This enables the pflogd daemon that brings up an interface named pflog0 and writes logs in binary format to a file named /var/log/pflog. Logs can be parsed in realtime from the interface, or read from the /var/log/pflog file with the tcpdump(8) utility.

      First access some logs from the /var/log/pflog file:

      • sudo tcpdump -ner /var/log/pflog

      You pass the -ner flags that format the output for readability, and also specify a file to read from, which in your case is /var/log/pflog.

      You will see the following output:

      Output

      reading from file /var/log/pflog, link-type PFLOG (OpenBSD pflog file)

      In these early stages there may not be any data in the /var/log/pflog file. In a short period of time the log file will begin to grow.

      You can also view logs in realtime from the pflog0 interface by using the following command:

      You pass the -nei flags, which also format the output for readability, but this time specify an interface, which in your case is pflog0.

      You will see the following output:

      Output

      tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 262144 bytes

      You will now see connections in realtime. If possible, ping your server from a remote machine and you will see the connections occurring. The server will remain in this state until you exit out of it.

      To exit out of this state and return to the command line hit CTRL + Z.

      There is a wealth of information on the internet about tcpdump(8), including the official website.

      Accessing Log Files with pftop

      The pftop utility is a tool for quickly viewing firewall activity in realtime. Its name is influenced by the well-known Unix top utility.

      To use it, you need to install the pftop package:

      Now run the pftop binary:

      This will generate the following output (your IPs will differ):

      Output

      PR DIR SRC DEST STATE AGE EXP PKTS BYTES tcp In 251.155.237.90:27537 157.225.173.58:22 ESTABLISHED:ESTABLISHED 00:12:35 23:59:55 1890 265K tcp In 222.186.42.15:25884 157.225.173.58:22 TIME_WAIT:TIME_WAIT 00:01:25 00:00:06 22 3801 udp Out 157.245.171.59:4699 67.203.62.5:53 MULTIPLE:SINGLE 00:00:14 00:00:16 2 227

      Creating Additional Log Interfaces

      Like any other interface, multiple log interfaces can be created and named with a /etc/hostname file. You may find this useful for organizational purposes, for example if you want to log certain types of activity separately.

      Create an additional logging interface named pflog1:

      • sudo vi /etc/hostname.pflog1

      Add the following contents to the /etc/hostname.pflog1 file:

      /etc/hostname.pflog1

      up
      

      Now enable the device at boot-time in your /etc/rc.conf file:

      • sudo sysrc pflog1_enable="YES"

      You can now monitor and log your firewall activity. This allows you to see who is making connections to your server and the types of connections being made.

      Throughout this tutorial you’ve incorporated some advanced concepts into your PF ruleset. It’s only necessary to implement advanced features as you need them. That said, in the next step you’ll revert back to the base ruleset.

      Step 8 — Reverting Back to Your Base Ruleset (Optional)

      In this final section you’ll revert back to your base ruleset. This is a quick step that will bring you back to a minimalist state of functionality.

      Open the base ruleset with the following command:

      Delete the current ruleset in your file and replace it with the following base ruleset:

      /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach }"
      table <bruteforce> persist
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      antispoof quick for $vtnet0
      block in quick on $vtnet0 from <rfc6890>
      block return out quick on egress to <rfc6890>
      block all
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass inet proto icmp icmp-type $icmp_types
      

      Save and exit the file.

      Reload the ruleset:

      • sudo pfctl -f /etc/pf.conf

      If there are no errors from the command, then there are no errors in your ruleset and your firewall is functioning properly.

      You also need to disable the pflog1 interface that you created. Since you might not know if you need it yet, you can disable pflog1 with the sysrc utility:

      • sudo sysrc pflog1_enable="NO"

      Now remove the /etc/hostname.pflog1 file from the /etc directory:

      • sudo rm /etc/hostname.pflog1

      Before signing off, reboot the server once more to ensure that all of your changes are active and persistent:

      Wait a few minutes before logging in to your server.

      Optionally, if you would like to implement PF with a webserver, the following is a ruleset for this scenario. This ruleset is a sufficient starting point for most web applications.

      Simple Web Server Ruleset

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach }"
      table <bruteforce> persist
      table <webcrawlers> persist
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      antispoof quick for $vtnet0
      block in quick on $vtnet0 from <rfc6890>
      block return out quick on egress to <rfc6890>
      block all
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      pass in on $vtnet0 proto tcp to port { 80 443 } 
          keep state (max-src-conn 45, max-src-conn-rate 9/1, 
              overload <webcrawlers> flush global)
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass inet proto icmp icmp-type $icmp_types
      

      This creates an overload table named <webcrawlers>, which has a more liberal overload policy than your SSH port based on the values of max-src-conn 45 and max-src-conn-rate. This is because not all overloads are from bad actors. They also can originate from non-malicious netbots, so you avoid excessive security measures on ports 80 and 443. If you decide to implement the webserver ruleset, you need to add the <webcrawlers> table to /etc/pf.conf, and clear the IPs from the table periodically. Refer to Step 5 for this.

      Conclusion

      In this tutorial, you configured PF on FreeBSD 12.1. You now have a base ruleset that can serve as a starting point for all of your FreeBSD projects. For further information on PF take a look at the pf.conf(5) man pages.

      Visit our FreeBSD topic page for more tutorials and Q&A.



      Source link

      Pasos recomendados para reforzar un servidor HTTP de Apache en FreeBSD 12.0


      El autor seleccionó la Free and Open Source Fund para recibir una donación como parte del programa Write for DOnations.

      Introducción

      Aunque la instalación predeterminada de un servidor HTTP Apache ya es segura, la configuración puede mejorar en gran medida con algunas modificaciones. Puede complementar los mecanismos de seguridad ya existentes, por ejemplo, estableciendo protecciones en torno a las cookies y los encabezados, de modo que las conexiones no se puedan manipular al nivel de cliente del usuario. Realizando esto puede reducir notablemente las posibilidades de exponerse a varios métodos de ataque, como los de secuencias de comandos entre sitios (también conocidos como XSS). También puede evitar otros tipos de ataques, como la falsificación de solicitudes entre sitios, los secuestros de sesiones o la denegación de servicios.

      A lo largo de este tutorial, implementará algunos pasos recomendados para reducir la cantidad de información expuesta en su servidor. Verificará los listados de directorios y desactivará la indexación para chequear el acceso a recursos. También cambiará el valor predeterminado de la directiva timeout para poder mitigar el tipo de ataque de denegación de servicio. Además, desactivará el método TRACE para que las sesiones no se puedan revocar ni secuestrar. Por último, protegerá los encabezados y las cookies.

      La mayoría de los ajustes de configuración se aplicarán al archivo de configuración principal del servidor HTTP Apache ubicado en /usr/local/etc/apache24/httpd.conf.

      Requisitos previos

      Para completar esta guía, necesitará lo siguiente:

      Una vez completados los requisitos previos tendrá un sistema de FreeBSD con una pila adicional capaz de proporcionar contenido web usando cualquier cosa escrita en PHP, como un software importante de CMS. Además, cifró conexiones seguras a través de Let´s Encrypt.

      Reducir la información del servidor

      El banner del sistema operativo es un método utilizado por computadoras, servidores y dispositivos de todo tipo para presentarse en las redes. Individuos malintencionados pueden usar esta información para obtener beneficios de explotación en los sistemas en cuestión. En esta sección, reducirá la cantidad de información publicada por este banner.

      En los conjuntos de directivas se controla la manera en la que se muestra esta información. Para esto, es importante la directiva ServerTokens; por defecto, muestra toda la información sobre el sistema operativo y los módulos compilados al cliente que establece conexión.

      Antes de aplicar cualquier cambio, usará una herramienta para escanear la red y verificar la información que se muestra actualmente. Para instalar nmap ejecute el siguiente comando:

      Para obtener la dirección IP de su servidor, puede ejecutar el siguiente comando:

      • ifconfig vtnet0 | awk '/inet / {print $2}'

      Puede verificar la respuesta del servidor web usando el siguiente comando:

      • nmap -sV -p 80 your-server-ip

      Invoca nmap para hacer un escaneo (por ello se usa el indicador -s), a fin de mostrar la versión (el indicador -V) en el puerto 80 (el indicador -p) en el IP o dominio determinado.

      Recibirá información sobre su servidor web similar a la siguiente:

      Output

      Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-22 00:30 CET Nmap scan report for 206.189.123.232 Host is up (0.054s latency). PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.41 ((FreeBSD) OpenSSL/1.1.1d-freebsd Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 7.59 seconds

      En el resultado se muestra que la información como la del sistema operativo, la versión del servidor HTTP Apache y OpenSSL es visible. Esto puede ser útil para que los atacantes obtengan información sobre el servidor y elijan las herramientas adecuadas para explotar, por ejemplo, una vulnerabilidad en el software que se ejecuta en el servidor.

      Disponga la directiva ServerTokens en el archivo de configuración principal, ya que no viene configurada por defecto. La falta de esta configuración hace que el servidor HTTP Apache muestre su información completa como se indica en la documentación. Para limitar la información que se muestra acerca de su servidor y configuración, dispondrá la directiva ServerTokens dentro del archivo de configuración principal.

      Dispondrá esta directiva después de la entrada de ServerName en el archivo de configuración. Ejecute el siguiente comando para encontrar la directiva:

      • grep -n 'ServerName' /usr/local/etc/apache24/httpd.conf

      Encontrará el número de línea que luego podrá buscar con vi:

      Output

      226 #ServerName www.example.com:80

      Ejecute el siguiente comando:

      • sudo vi +226 /usr/local/etc/apache24/httpd.conf

      Añada la siguiente línea resaltada:

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

      . . .
      #ServerName www.example.com:80
      ServerTokens Prod
      

      Guarde y cierre el archivo con :wq e INTRO.

      Fijar la directiva ServerTokens en Prod hará que solo se muestre que este es un servidor web de Apache.

      Para que esto se implemente, reinicie el servidor HTTP Apache:

      Para probar los cambios, ejecute el siguiente comando:

      • nmap -sV -p 80 your-server-ip

      Verá un resultado similar al siguiente con la información mínima adicional acerca de su servidor web de Apache:

      Output

      Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-22 00:58 CET Nmap scan report for WPressBSD (206.189.123.232) Host is up (0.056s latency). PORT STATE SERVICE VERSION 80/tcp open http Apache httpd Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 7.59 seconds

      Vio la información que se anunciaba en el servidor antes del cambio y ahora la redujo al mínimo. Con esto, proporcionará a un agente externo menos pistas acerca de su servidor. En el siguiente paso, administrará los listados de directorios para su servidor web.

      Administrar los listados de directorios

      En este paso, se asegurará de que el listado de directorios esté configurado correctamente para que las partes adecuadas del sistema estén disponibles públicamente como se espera, mientras el resto quede protegido.

      Nota: Cuando se declara un argumento, este está activo, pero el signo + puede reforzar por medios visuales la sugerencia de que efectivamente se encuentra habilitado. Cuando se dispone un signo menos - el argumento se niega; por ejemplo, Options -Indexes.

      Los argumentos con + o con - no se pueden mezclar, se consideran como elementos de mala sintaxis en el servidor HTTP Apache y se pueden rechazar al inicio.

      Añadir la instrucción Options -Indexes establecerá el contenido dentro de la ruta de datos /usr/local/www/apache24/data para no realizar la indexación (leer listado) de forma automática si no existe un archivo .html y no mostrar si una URL asigna este directorio. Esto también se aplicará al utilizar configuraciones de host virtuales como la que se emplea para el tutorial de requisitos previos para el certificado de Let´s Encrypt.

      Establecerá la directiva Options con el argumento -Indexes y con la directiva +FollowSymLinks, que permitirá el seguimiento de los enlaces simbólicos. Usará el símbolo + para cumplir con las convenciones HTTP de Apache.

      Ejecute el siguiente comando para encontrar la línea que editará en el archivo de configuración:

      • grep -n 'Options Indexes FollowSymLinks' /usr/local/etc/apache24/httpd.conf

      Visualizará un resultado similar al siguiente:

      Output

      263 : Options Indexes FollowSymLinks

      Ejecute este comando para acceder de manera directa a la línea para editar:

      • sudo vi +263 /usr/local/etc/apache24/httpd.conf

      Ahora, edite la línea conforme a la configuración:

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

      . . .
      #
      Options -Indexes +FollowSymLinks
      
      #
      . . .
      

      Guarde y cierre el archivo con :wq e INTRO.

      Reinicie el servidor HTTP Apache para implementar estos cambios:

      En su dominio en el navegador, verá un mensaje de acceso prohibido, también conocido como el error 403. Esto se debe a los cambios que implementó. Con la disposición de -Indexes en la directiva Options se desactivó la capacidad de aplicar indexación de forma automática en el servidor HTTP Apache y, por lo tanto, no existe un archivo index.html dentro de la ruta de datos.

      Puede solucionar esto disponiendo un archivo index.html dentro del VirtualHost habilitado en el tutorial de requisitos previos para el certificado de Let´s Encrypt. Usará el bloque predeterminado dentro de HTTP Apache y lo dispondrá en la misma carpeta que el DocumentRoot que declaró en el host virtual.

      /usr/local/etc/apache24/extra/httpd-vhosts.conf

      <VirtualHost *:80>
          ServerAdmin your_email@your_domain.com
          DocumentRoot "/usr/local/www/apache24/data/your_domain.com"
          ServerName your_domain.com
          ServerAlias www.your_domain.com
          ErrorLog "/var/log/your_domain.com-error_log"
          CustomLog "/var/log/your_domain.com-access_log" common
      </VirtualHost>
      

      Para hacerlo utilice el siguiente comando:

      • sudo cp /usr/local/www/apache24/data/index.html /usr/local/www/apache24/data/your_domain.com/index.html

      Ahora, cuando visite su dominio verá un mensaje It works!

      En esta sección, estableció restricciones a la directiva Indexes para no escribir y mostrar de forma automática contenido diferente del que pretende. Si no existe un archivo index.html dentro de la ruta de datos, en el servidor HTTP Apache no se creará de manera automática un índice de contenidos. En el siguiente paso, irá más allá del ocultamiento de información y personalizará diferentes directivas.

      Reducir el valor de la directiva Timeout

      La directiva Timeout establece el límite de tiempo que el servidor HTTP Apache otorgará para nuevas entradas o salidas antes de que falle la solicitud de conexión. Esta falla puede producirse debido a diferentes circunstancias, como los casos en que los paquetes no llegan al servidor o el cliente no confirma como recibidos los datos.

      Por defecto, el tiempo de espera se fija en 60 segundos. En los entornos en los cuales el servicio de Internet es lento, este valor predeterminado puede ser razonable, pero un minuto es bastante tiempo; en particular, si el servidor abarca un grupo de usuarios con un servicio de Internet más rápido. Además, el tiempo durante el cual no se cierra la conexión en el servidor puede aprovecharse para ataques de denegación de servicio (DoS). Si se produce una sobrecarga de estas conexiones malintencionadas, el servidor se bloqueará, y posiblemente se saturará y no responderá.

      Para cambiar el valor encontrará las entradas de Timeout en el archivo httpd-default.conf:

      • grep -n 'Timeout' /usr/local/etc/apache24/extra/httpd-default.conf

      Verá un resultado similar al siguiente:

      Output

      8 # Timeout: The number of seconds before receives and sends time out. 10 Timeout 60 26 # KeepAliveTimeout: Number of seconds to wait for the next request from the 29 KeepAliveTimeout 5 89 RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500

      En la línea de salida, se fija el valor de la directiva Timeout en 10. Para acceder directamente a esta línea, ejecute el siguiente comando:

      • sudo vi +10 /usr/local/etc/apache24/extra/httpd-default.conf

      La cambiará a 30 segundos, por ejemplo, como en el siguiente ejemplo:

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

      #
      # Timeout: The number of seconds before receives and sends time out.
      #
      Timeout 30
      

      Guarde y cierre el archivo con :wq e INTRO.

      En el valor de la directiva Timeout se debe equilibrar un rango de tiempo suficientemente extenso como para que estos eventos permitan que se establezca una conexión legítima y exitosa, pero suficientemente breve como para evitar los intentos de conexiones no deseadas.

      Nota: Los ataques de denegación de servicio pueden drenar los recursos del servidor de forma eficaz. Una medida complementaria y muy eficaz para contrarrestar esto consiste en usar un MPM anidado para obtener el mejor rendimiento en cuanto a la forma en que se manejan las conexiones y los procesos en el servidor HTTP Apache. En el tutorial Cómo configurar HTTP Apache con MPM Event y PHP-FPM en FreeBSD 12.0 se ofrecen pasos para habilitar esta capacidad.

      Para que este cambio tenga efecto, reinicie el servidor HTTP Apache:

      Cambió el valor predeterminado de la directiva Timeout para mitigar parcialmente los ataques de DoS.

      Deshabilitar el método TRACE

      El Protocolo de transferencia de hipertexto se desarrolló siguiendo un modelo de servidor y cliente y, como tal, en el protocolo existen métodos de solicitud para recuperar o disponer información desde el servidor o en él. El servidor debe interpretar estos conjuntos de métodos y la interacción entre ellos. En este paso, configurará los métodos básicos necesarios.

      El método TRACE, que se consideraba inofensivo, se aprovechó para realizar ataques de rastreo entre sitios. Este tipo de ataques permite a individuos malintencionados robar sesiones de los usuarios a través del método. El método se diseñó para la depuración a través del servidor devolviendo la misma solicitud originalmente enviada por el cliente. Debido a que la cookie de la sesión del navegador se envía al servidor, se enviará de regreso nuevamente. Sin embargo, un individuo malintencionado podría interceptar esto y luego redirigir la conexión de un navegador a un sitio bajo su control y no al servidor original.

      Debido a la posibilidad del mal uso que se puede dar al método TRACE, se recomienda usarlo únicamente para la depuración y no en la producción. En esta sección, desactivará este método.

      Edite el archivo httpd.conf con el siguiente comando y presione G para llegar al final del archivo:

      • sudo vi /usr/local/etc/apache24/httpd.conf

      Añada la siguiente ruta de entrada al final del archivo:

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

      . . .
      TraceEnable off
      

      Se recomienda especificar únicamente los métodos que usará en su servidor web HTTP Apache. Esto ayudará a limitar los puntos de entrada potenciales para los individuos malintencionados.

      LimitExcept puede ser útil para este propósito, ya que no se permitirán otros métodos aparte de los declarados en este. Por ejemplo, puede establecer una configuración como la siguiente:

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

      DocumentRoot "/usr/local/www/apache24/data"
      <Directory "/usr/local/www/apache24/data">
          Options -Indexes +FollowSymLinks -Includes
          AllowOverride none
           <LimitExcept GET POST HEAD>
             deny from all
          </LimitExcept>
          Require all granted
      </Directory>
      

      Como se declara en la directiva LimitExcept solo se permiten los métodos GET, POST y Head en la configuración.

      • El método GET es parte del protocolo HTTP y se utiliza para recuperar datos.
      • El método POST también es parte del protocolo HTTP y se utiliza para enviar datos al servidor.
      • El método HEAD es similar a GET. Sin embargo, no tiene cuerpo de respuesta.

      Usará el siguiente comando y dispondrá el bloque de LimitExcept dentro del archivo:

      • sudo vi +272 /usr/local/etc/apache24/httpd.conf

      Para establecer esta configuración, dispondrá el siguiente bloque en la entrada de la directiva DocumentRoot de donde se leerá el contenido, más específicamente dentro de la entrada Directory.

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

      . . .
      <LimitExcept GET POST HEAD>
         deny from all
      </LimitExcept>
      . . .
      

      Para implementar los cambios, reinicie el servidor HTTP Apache:

      En la directiva más reciente AllowedMethods se proporciona una funcionalidad similar, aunque su estado es aún experimental.

      Vio los métodos HTTP, su uso y la protección que ofrecen contra la actividad malintencionada que se aprovecha del método TRACE, así como la forma de declarar los métodos que se usarán. A continuación, trabajará con más protecciones dedicadas a los encabezados y las cookies HTTP.

      Proteger los encabezados y las cookies

      En este paso, establecerá directivas específicas para proteger las sesiones que se abrirán en las máquinas cliente cuando visite su servidor web HTTP Apache. De esta manera, en su servidor no se cargará contenido no deseado, el cifrado no se degradará y evitará el espionaje de contenido.

      Los encabezados son componentes de los métodos de solicitudes. Existen encabezados para ajustar la autenticación, la comunicación entre el servidor y el cliente, el almacenamiento en caché y la negociación de contenido, entre otros aspectos.

      Las cookies son pequeños fragmentos de información que el servidor envía al navegador. Estos pequeños fragmentos permiten que en el servidor se reconozca el navegador del cliente de una computadora a otra. También permiten que en los servidores se reconozcan sesiones de usuarios. Por ejemplo, se puede hacer un seguimiento del carrito de compras de un usuario que inició sesión, la información de pago y el historial, entre otros datos. Las cookies se utilizan y se conservan en el navegador web del cliente, ya que HTTP es un protocolo sin estado; esto significa que cuando la conexión se cierra en el servidor no se registra la solicitud enviada por uno u otro cliente.

      Es importante proteger los encabezados y las cookies porque permiten la comunicación entre el cliente del navegador web y el servidor web.

      El módulo headers viene activado por defecto. Para verificar si está cargado, usará el siguiente comando:

      • sudo apachectl -M | grep 'headers'

      Verá el siguiente resultado:

      Output

      headers_module (shared)

      Si no ve un resultado, verifique si el módulo está activo dentro del archivo httpd.conf de Apache:

      • grep -n 'mod_headers' /usr/local/etc/apache24/httpd.conf

      Como resultado, verá una línea sin comentarios con referencia al módulo específico para encabezados:

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

      . . .
      122  LoadModule headers_module libexec/apache24/mod_headers.so
      . . .
      

      Si está presente, elimine el hashtag al inicio de la línea mod_headers.so para activar la directiva.

      Usando las siguientes directivas HTTP de Apache, protegerá los encabezados y las cookies contra actividades malintencionadas para reducir el riesgo al que se exponen los clientes y los servidores.

      Ahora, configurará la protección del encabezado. Dispondrá todos estos valores de encabezado en un bloque. Puede optar por aplicar estos valores como lo desee, pero todos se recomiendan.

      Edite el archivo httpd.conf con el siguiente comando y presione G para llegar al final del archivo:

      • sudo vi /usr/local/etc/apache24/httpd.conf

      Disponga el siguiente bloque al final del archivo:

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

      . . .
      <IfModule mod_headers.c>
        # Add security and privacy related headers
        Header set Content-Security-Policy "default-src 'self'; upgrade-insecure-requests;"
        Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
        Header always edit Set-Cookie (.*) "$1; HttpOnly; Secure"
        Header set X-Content-Type-Options "nosniff"
        Header set X-XSS-Protection "1; mode=block"
        Header set Referrer-Policy "strict-origin"
        Header set X-Frame-Options: "deny"
        SetEnv modHeadersAvailable true
      </IfModule>
      
      • Header set Strict-Transport-Security "max-age=31536000; includeSubDomains": la seguridad estricta de transporte de HTTP (HTSTS) es un mecanismo para que los servidores y clientes web (principalmente navegadores) establezcan comunicaciones utilizando solo HTTPS. Al implementar esto evitará la presencia de atacantes desconocidos, en cuyo caso un tercero en medio de la comunicación podría acceder a los fragmentos de información y manipularlos.

      • Header always edit Set-Cookie (. *) "$1; HttpOnly; Secure": los indicadores HttpOnly y Secure en los encabezados ayudan a prevenir las secuencias de comandos entre sitios, también conocidas como XSS. Los atacantes pueden utilizar las cookies de forma indebida para simular ser visitantes legítimos al presentarse como otras personas (robo de identidad), o para ser manipuladas.

      • Header set Referrer-Policy "strict-origin": en el encabezado Referrer-Policy se establece la información que se incluye como información de referencia en el campo de encabezado.

      • Header set Content-Security-Policy "default-src 'self'; upgrade-insecure-requests;": en el encabezado de Content-Security-Policy (CSP) se evitará por completo la carga de contenido que no esté especificada en los parámetros, lo cual es útil para evitar las secuencias de comandos en sitios cruzados (XSS). Existen muchos parámetros posibles para configurar la política de este encabezado. El objetivo final es configurarlo para cargar contenido del mismo sitio y actualizar cualquier contenido con un origen HTTP.

      • Header set X-XSS-Protection "1; mode=block": esto es compatible con navegadores antiguos en los que no se procesan encabezados Content-Security-Policy. En el encabezado ‘X-XSS-Protection’ se ofrece protección contra secuencias de comandos entre sitios. No necesita configurar este encabezado a menos que se necesite compatibilidad con versiones anteriores de navegadores, lo cual es poco común.

      • Header set X-Frame-Options: "deny": con esto se evitan ataques de clickjacking (secuestro de clics). En el encabezado ‘X-Frame-Options’ se indica a un navegador si una página se puede presentar en <frame>, <iframe>, <embed> o <object>. De esta manera, los contenidos de sitios diferentes no pueden integrarse a otros, lo cual previene los ataques de clickjacking. Aquí, niega toda la presentación de marco para que la página web no se pueda integrar en otro lugar, ni siquiera dentro del mismo sitio web. Puede adecuar esto a sus necesidades si, por ejemplo, debe autorizar la presentación de algunas páginas debido a que son anuncios o colaboraciones con sitios web específicos.

      • Header set X-Content-Type-Options "nosniff": en el encabezado ‘X-Content-Type-Options’ se controlan los tipos MIME para que no se sometan a cambios ni a seguimiento. Los tipos MIME son estándares de formatos de archivo; funcionan para texto, audio, video e imagen, entre otros. Con este encabezado se bloquean los intentos de espiar dichos archivos y modificar sus tipos por parte de individuos malintencionados.

      Ahora, reinicie Apache para implementar los cambios:

      Para evaluar los niveles de seguridad de sus configuraciones, consulte el sitio web de Security Headers. Después de seguir los pasos de este tutorial, la calificación de su dominio será A.

      Nota: Si evalúa sus encabezados visitando https://securityheaders.com/ y obtiene una calificación F, podría deberse a que index.html no se encuentra dentro del DocumentRoot de su sitio, como se indica al final del paso 2. Si cuando evalúa sus encabezados obtiene una calificación que no sea a A o sea F, revise cada línea Header set en busca de cualquier error ortográfico que pueda haber causado una calificación menor.

      En este paso, trabajó con hasta siete configuraciones para mejorar la seguridad de sus encabezados y cookies. Esto permitirá evitar las secuencias de comandos entre sitios, el clickjacking y otros tipos de ataques.

      Conclusión

      En este tutorial, se abordaron varios aspectos relacionados con la seguridad, desde la divulgación de información hasta la protección de las sesiones y el ajuste de parámetros de configuración alternativos para funciones importantes.

      Si desea obtener más información sobre el reforzamiento de Apache, a continuación se ofrecen algunas otras referencias:

      Si desea acceder a más herramientas para la protección del servidor HTTP Apache:

      • mod_evasive es una herramienta útil para ayudar a mitigar los ataques de DoS. Puede encontrar más información en el tutorial Cómo protegerse contra DoS y DDoS con mod_evasive para Apache.

      • freail2ban es un software de prevención de intrusiones que es útil para bloquear intentos de inicio de sesión repetidos por parte de usuarios no autorizados. Puede obtener más información acerca de esto en el tutorial Cómo proteger un servidor Apache con Fail2Ban.

      • ModSecurity es un Firewall de aplicación web (o WAF) y, como tal, ofrece una amplia variedad de posibilidades basada en reglas predefinidas escritas por SpyderLabs y miembros de la comunidad. Puede leer más acerca de esto en el tutorial Cómo configurar ModSecurity con Apache.



      Source link

      Рекомендованные меры для усиления безопасности Apache HTTP во FreeBSD 12.0


      Автор выбрал фонд Free and Open Source Fund для получения пожертвования в рамках программы Write for DOnations.

      Введение

      Хотя используемая по умолчанию установка сервера Apache HTTP безопасна для использования, ее конфигурацию можно значительно улучшить с помощью нескольких изменений. Вы можете дополнить уже существующие механизмы безопасности, например, настроив защиту для cookie-файлов и заголовков, чтобы подключения нельзя было перехватывать на уровне клиента пользователя. Благодаря этому вы сможете значительно снизить вероятность атак с использованием ряда методов, например, атаки с помощью межсайтового выполнения сценариев (XSS). Также вы можете предотвратить другие виды атак, в том числе подделку межсайтовых запросов, перехват сеанса, а также DoS-атаки.

      В этом обучающем руководстве мы реализуем некоторые рекомендуемые меры, которые помогут снизить видимость информации, размещенной на вашем сервере. Вы научитесь проверять списки директорий и отключать индексирование для проверки доступа к ресурсам. Также вы сможете изменять используемое по умолчанию значение директивы timeout для борьбы с последствиями DoS-атак. Кроме того, вы узнаете, как отключить метод TRACE, чтобы сеансы нельзя было переключить или взломать. А в конце вы научитесь обеспечивать безопасность заголовков и cookie-файлов.

      Большинство настроек конфигурации будет применяться для основного файла конфигурации Apache HTTP, расположенного по адресу /usr/local/etc/apache24/httpd.conf.

      Предварительные требования

      Для прохождения этого обучающего руководства вам потребуется следующее:

      Когда все необходимое будет у вас в распоряжении, вы получите систему FreeBSD со стеком, позволяющим обслуживать веб-контент с помощью любого ПО, написанного на PHP, например, популярных CMS-систем. За безопасность подключений будет отвечать Let’s Encrypt.

      Сокращение доступной информации о сервере

      Баннер операционной системы — это метод, используемый компьютерами, серверами и устройствами всех типов для представления информации о себе в сетях. Злоумышленники могут использовать эту информацию для применения эксплойтов в соответствующих системах. В этом разделе вы сможете сократить количество информации, которое содержит этот баннер.

      Набор директив контролирует то, как отображается эта информация. Для нашей цели самой важной директивой будет ServerTokens; по умолчанию она отображает все данные об операционной системе и скомпилированных модулях для клиента, который подключается к ней.

      Вы должны воспользоваться инструментом для сетевого сканирования для проверки того, какая информация в настоящее время раскрывается, прежде чем вносить любые изменения. Чтобы установить nmap, запустите следующую команду:

      Чтобы получить IP-адрес вашего сервера, вы можете воспользоваться следующей командой:

      • ifconfig vtnet0 | awk '/inet / {print $2}'

      Для проверки ответа веб-сервера используйте следующую команду:

      • nmap -sV -p 80 your-server-ip

      Вызовите nmap для выполнения сканирования (используйте флаг -s), для вывода версии (используйте флаг -V) на порту 80 (используйте флаг -p) на указанном IP-адресе или домене.

      Вы получите информацию о вашем веб-сервере примерно в следующем виде:

      Output

      Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-22 00:30 CET Nmap scan report for 206.189.123.232 Host is up (0.054s latency). PORT STATE SERVICE VERSION 80/tcp open http Apache httpd 2.4.41 ((FreeBSD) OpenSSL/1.1.1d-freebsd Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 7.59 seconds

      Данный вывод показывает, что такая информация, как операционная система, версия Apache HTTP и OpenSSL, является видимой. Она может использоваться злоумышленниками для получения данных о сервере и выбора необходимых инструментов для использования уязвимостей, например, уязвимостей установленного на сервере ПО.

      Добавьте директиву ServerTokens в основной файл конфигурации, поскольку она не настроена по умолчанию. Отсутствие такой настройки заставляет Apache HTTP отображать полную информацию о сервере согласно требованиям документации. Чтобы ограничить объем отображаемой информации о вашем сервере и конфигурации, поместите директиву ServerTokens в основной файл конфигурации.

      Добавьте эту директиву после записи ServerName в файле конфигурации. Запустите следующую команду для поиска директивы:

      • grep -n 'ServerName' /usr/local/etc/apache24/httpd.conf

      Вы получите номер строки, которую затем сможете найти с помощью vi:

      Output

      226 #ServerName www.example.com:80

      Запустите следующую команду:

      • sudo vi +226 /usr/local/etc/apache24/httpd.conf

      Затем добавьте следующую выделенную строку:

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

      . . .
      #ServerName www.example.com:80
      ServerTokens Prod
      

      Сохраните и закройте файл, введя :wq и нажав ENTER.

      Если для директивы ServerTokens указано значение Prod, она будет отображать только информацию о том, что это веб-сервер Apache.

      Чтобы изменения вступили в силу, перезапустите сервер Apache HTTP:

      Чтобы протестировать изменения, запустите следующую команду:

      • nmap -sV -p 80 your-server-ip

      Вывод будет выглядеть примерно следующим образом и содержать более сжатую информацию о веб-сервере Apache:

      Output

      Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-22 00:58 CET Nmap scan report for WPressBSD (206.189.123.232) Host is up (0.056s latency). PORT STATE SERVICE VERSION 80/tcp open http Apache httpd Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 7.59 seconds

      Вы видели, какая информация о сервере отображалась до внесения изменений, а сейчас мы смогли сократить ее количество до минимума. Благодаря этому вы предоставляете меньше данных о вашем сервере сторонним акторам. На следующем шаге вы научитесь управлять списками директорий вашего веб-сервера.

      Управление списками директорий

      На этом шаге вы сможете убедиться, что список директорий настроен корректно, поэтому необходимые части системы доступны публично, а остальная часть закрыта.

      Примечание. Когда аргумент объявляется, он становится активен, но символ + может визуально подтверждать, что он активен. Использование знака минус - говорит о том, что аргумент отклонен, например, Options -Indexes.

      Аргументы со знаками + и/или - нельзя смешивать, подобная конструкция считается некорректным синтаксисом в Apache HTTP и может быть отклонена при запуске.

      Добавление оператора Options -Indexes​​​ отключает индексирование контента внутри пути /usr/local/www/apache24/data (read listed) автоматически, если файл .html отсутствует, и запрещает отображение, если URL видит эту директорию. Также подобная практика будет применяться при использовании конфигураций виртуального хоста, например, хоста, используемого согласно предварительным требованиям для размещения сертификата Let’s Encrypt.

      Вы задаете для директивы Options аргумент -Indexes и используете директиву +FollowSymLinks, которая позволит использовать символьные ссылки. Вы должны также воспользоваться символом + для соблюдения конвенций Apache HTTP.

      Запустите следующую команду для получения строки для редактирования в файле конфигурации:

      • grep -n 'Options Indexes FollowSymLinks' /usr/local/etc/apache24/httpd.conf

      Результат будет выглядеть примерно так:

      Output

      263 : Options Indexes FollowSymLinks

      Запустите следующую команду для прямого доступа к строке для редактирования:

      • sudo vi +263 /usr/local/etc/apache24/httpd.conf

      Теперь вы можете изменить строку согласно желаемой конфигурации:

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

      . . .
      #
      Options -Indexes +FollowSymLinks
      
      #
      . . .
      

      Сохраните и закройте файл, введя :wq и нажав ENTER.

      Перезапустите Apache HTTP для вступления изменений в силу:

      В браузере при попытке входа на домен вы увидите сообщение о запрете доступа (ошибку 403). Это результат внесенных вами изменений. Добавление -Indexes в директиву Options позволило отключить автоматическое индексирование Apache HTTP, в результате чего файл index.html по указанному пути отсутствует.

      Вы можете решить эту проблему, разместив файл index.html внутри виртуального хоста (VirtualHost), который вы активировали согласно предварительным требованиям для использования сертификата Let’s Encrypt. Вам нужно будет воспользоваться блоком по умолчанию внутри Apache HTTP и разместить его в той же папке, что и DocumentRoot, объявленный в виртуальном хосте.

      /usr/local/etc/apache24/extra/httpd-vhosts.conf

      <VirtualHost *:80>
          ServerAdmin your_email@your_domain.com
          DocumentRoot "/usr/local/www/apache24/data/your_domain.com"
          ServerName your_domain.com
          ServerAlias www.your_domain.com
          ErrorLog "/var/log/your_domain.com-error_log"
          CustomLog "/var/log/your_domain.com-access_log" common
      </VirtualHost>
      

      Для этого используйте следующую команду:

      • sudo cp /usr/local/www/apache24/data/index.html /usr/local/www/apache24/data/your_domain.com/index.html

      Теперь вы должны увидеть сообщение It works! при посещении вашего домена.

      В этом разделе вы добавили ограничения для директивы Indexes и запретили автоматическое включение в список и отображение контента, за исключением того, который вы опубликовали намеренно. Теперь, если файл index.html отсутствует внутри пути данных, Apache HTTP не будет автоматически создавать индекс содержимого. На следующем шаге мы перейдем к дальнейшему сокрытию данных и настроим другие директивы.

      Снижение значения директивы Timeout

      Директива Timeout задает лимит времени, в течение которого Apache HTTP будет ждать нового ввода/вывода, прежде чем отклонять запрос подключения. Такие проблемы могут возникать в силу разных обстоятельств, например, в случае, если пакеты не будут поступать на сервер или данные не будут подтверждены как полученные клиентом.

      По умолчанию для директивы timeout задается значение 60 секунд. В условиях медленного подключения к Интернету такое значение по умолчанию может быть разумным, но одна минута — это довольно долго, особенно если сервер обслуживает пользователей с быстрым доступом в Интернет. Кроме того, время, когда сервер не закрывает соединение, может быть использовано для совершения DoS-атак. При большом количестве злонамеренных подключений сервер может не справляться, а его работа может замедляться.

      Чтобы изменить значение, найдите записи Timeout в файле httpd-default.conf:

      • grep -n 'Timeout' /usr/local/etc/apache24/extra/httpd-default.conf

      Вывод будет выглядеть примерно следующим образом:

      Output

      8 # Timeout: The number of seconds before receives and sends time out. 10 Timeout 60 26 # KeepAliveTimeout: Number of seconds to wait for the next request from the 29 KeepAliveTimeout 5 89 RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500

      В строке вывода 10 задается значение директивы Timeout. Чтобы получить доступ к этой строке, запустите следующую команду:

      • sudo vi +10 /usr/local/etc/apache24/extra/httpd-default.conf

      Вы должны изменить значение на 30 секунд, например, следующим образом:

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

      #
      # Timeout: The number of seconds before receives and sends time out.
      #
      Timeout 30
      

      Сохраните и закройте файл, введя :wq и нажав ENTER.

      Значение директивы Timeout должно обеспечивать баланс между временем, достаточно долгим, чтобы создавать надежные и успешные подключения, но достаточно коротким, чтобы не допустить нежелательных попыток подключения.

      Примечание. DoS-атаки могут очень легко истощать все ресурсы сервера. Дополнительной и очень эффективной контрмерой является использование поточного MPM для достижения наилучших результатов работы Apache HTTP с подключениями и процессами. В руководстве Настройка Apache HTTP с MPM Event и PHP-FPM во FreeBSD 12.0 описаны шаги для активации этой возможности.

      Чтобы изменения вступили в силу, перезапустите сервер Apache HTTP:

      Вы изменили значение директивы Timeout по умолчанию для частичного смягчения последствий DoS-атак.

      Отключение метода TRACE

      Гипертекстовый транспортный протокол был разработан в соответствии с моделью клиент-сервер, и как таковой этот протокол имеет методы для получения или размещения информации от сервера и на сервере. Сервер должен понимать эти наборы методов и взаимодействие между ними. На этом шаге вы настроите минимальный набор необходимых методов.

      Метод TRACE, который считался безвредным, стал инструментом для совершения атак с помощью межсайтового отслеживания. Атаки такого типа позволяют злоумышленникам красть сеансы пользователя с помощью этого метода. Метод был создан для отладки, когда сервер возвращает тот же запрос, который первоначально отправляется клиентом. Поскольку cookie из сеанса браузера отправляются на сервер, они будут отправлены обратно. Однако эти cookie могут быть перехвачены злоумышленником, который затем может перенаправлять соединение браузера на находящийся под его контролем сайт, а не на оригинальный сервер.

      Из-за подобной возможности злонамеренного использования метода TRACE рекомендуется использовать его только в процессе отладки, не допуская в продакшен. В этом разделе вы отключите этот метод.

      Откройте файл httpd.conf с помощью следующей команды и нажмите G, чтобы перейти в самый конец файла:

      • sudo vi /usr/local/etc/apache24/httpd.conf

      Добавьте следующий путь входа в конце файла:

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

      . . .
      TraceEnable off
      

      Рекомендуется использовать только методы, которые вы будете использовать в вашем веб-сервере Apache HTTP. Это позволит ограничить потенциальные точки входа для злоумышленников.

      Директива LimitExcept может быть полезна в этом случае, запрещая использование любых других методов, кроме объявленных. Например, конфигурация в этом случае может выглядеть следующим образом:

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

      DocumentRoot "/usr/local/www/apache24/data"
      <Directory "/usr/local/www/apache24/data">
          Options -Indexes +FollowSymLinks -Includes
          AllowOverride none
           <LimitExcept GET POST HEAD>
             deny from all
          </LimitExcept>
          Require all granted
      </Directory>
      

      Как указано в директиве LimitExcept, в данной конфигурации допускаются только методы GET, POST и HEAD.

      • Метод GET является частью протокола HTTP и используется для получения данных.
      • Метод POST также является частью протокола HTTP и используется для отправки данных на сервер.
      • Метод HEAD похож на GET, но не имеет код для отправки ответа.

      Вы должны будете воспользоваться следующей командой и разместить блок LimitExcept внутри файла:

      • sudo vi +272 /usr/local/etc/apache24/httpd.conf

      Чтобы настроить конфигурацию, вы должны разместить следующий блок в строке директивы DocumentRoot, откуда будет считываться содержимое, а именно внутрь записи Directory:

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

      . . .
      <LimitExcept GET POST HEAD>
         deny from all
      </LimitExcept>
      . . .
      

      Чтобы применить изменения, перезапустите Apache HTTP:

      Новая версия директивы AllowedMethods предоставляет аналогичный функционал, хотя она пока используется в экспериментальном порядке.

      Вы увидели, что такое методы HTTP, порядок их использования и защиту от злоумышленников, которую они обеспечивают, на примере метода TRACE, а также процесс объявления того, какие методы разрешено использовать. Далее вам предстоит поработать над дополнительными мерами защиты для HTTP-заголовков и cookie-файлов.

      На этом шаге вы настроите конкретные директивы для защиты сеансов, которые будут создавать клиентские устройства при посещении вашего веб-сервера Apache HTTP. Таким образом ваш сервер не будет загружать нежелательный контент, средства шифрования не пострадают, а вы не станете жертвой отслеживания контента.

      Заголовки — это компоненты методов запроса. Существует заголовки для настройки аутентификации, связи между сервером и клиентом, кэширования, согласования содержимого и т. д.

      Cookie — это элементы информации, передаваемые сервером в браузер. Эти элементы позволяют серверу распознавать браузер клиента на разных компьютерах. Также они позволяют серверам распознавать сеансы пользователя. Например, они могут отслеживать корзину покупок зарегистрированного пользователя, платежную информацию, историю и т. д. Cookie-файлы используются и хранятся в браузере клиента, поскольку HTTP — это протокол без состояния, что означает, что после закрытия соединения сервер не запоминает запрос, отправленный тем или иным клиентом.

      Важно обеспечить защиту заголовков, а также cookie-файлов, поскольку они обеспечивают связь между веб-браузером клиента и веб-сервером.

      Модуль headers активирован по умолчанию. Чтобы убедиться, что он загружен, вы должны воспользоваться следующей командой:

      • sudo apachectl -M | grep 'headers'

      Вывод должен выглядеть так:

      Output

      headers_module (shared)

      Если вы не получили какого-либо результата, проверьте, включен ли модуль в файл Apache httpd.conf:

      • grep -n 'mod_headers' /usr/local/etc/apache24/httpd.conf

      В выводе вы должны увидеть незакомментированную строку, которая будет указывать на конкретный модуль для заголовков:

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

      . . .
      122  LoadModule headers_module libexec/apache24/mod_headers.so
      . . .
      

      Удалите хэштег в начале строки mod_headers.so, если он присутствует, чтобы активировать директиву.

      Используя следующие директивы Apache HTTP, вы сможете защитить заголовки и cookie от вредоносной активности, а также снизить возможные риски для клиентов и серверов.

      Теперь вы можете настроить защиту заголовка. Необходимо разместить все эти значения заголовка в одном блоке. Вы можете указывать любые значения, но рекомендуется использовать их все.

      Откройте файл httpd.conf с помощью следующей команды и нажмите G, чтобы перейти в самый конец файла:

      • sudo vi /usr/local/etc/apache24/httpd.conf

      Добавьте следующий блок в конце файла:

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

      . . .
      <IfModule mod_headers.c>
        # Add security and privacy related headers
        Header set Content-Security-Policy "default-src 'self'; upgrade-insecure-requests;"
        Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
        Header always edit Set-Cookie (.*) "$1; HttpOnly; Secure"
        Header set X-Content-Type-Options "nosniff"
        Header set X-XSS-Protection "1; mode=block"
        Header set Referrer-Policy "strict-origin"
        Header set X-Frame-Options: "deny"
        SetEnv modHeadersAvailable true
      </IfModule>
      
      • Header set Strict-Transport-Security "max-age=31536000; includeSubDomains": строгая безопасность передачи информации по протоколу HTTP (HTTP Strict Transport Security, HTSTS) — это используемый веб-серверами и клиентами (в основном браузерами) механизм коммуникации строго с помощью HTTPS. С помощью этого метода вы сможете избежать атак через посредника, когда третья сторона в процессе коммуникации может получить доступ к битам, а также вскрыть их.

      • Header always edit Set-Cookie (. *) "$1; HttpOnly; Secure":`флагиHttpOnlyиSecure` в заголовках помогают предотвратить атаки с использованием межсайтового выполнения сценариев (XSS). Cookie-файлы могут использоваться злоумышленниками, которые представляются кем-то другим (кража личности), или похищаться.

      • Header set Referrer-Policy "strict-origin": заголовок Referrer-Policy указывает, какая информация указывается в качестве информации об источнике ссылки в поле заголовка.

      • Header set Content-Security-Policy "default-src 'self'; upgrade-insecure-requests;": заголовок Content-Security-Policy (CSP) позволяет практически полностью предотвратить загрузку контента, не указанного в параметрах, что очень полезно для предотвращения атак с использованием межсайтового выполнения сценариев (XSS). Существует множество возможных параметров для настройки политики для этого заголовка. В целом необходимо настроить его для загрузки контента из одного сайта и обновления любого контента с происхождением из HTTP.

      • Header set X-XSS-Protection "1; mode=block": данный заголовок поддерживает старые браузеры, которые не работают с заголовками Content-Security-Policy. Заголовок ‘X-XSS-Protection’ обеспечивает защиту от атак с использованием межсайтового выполнения сценариев. Вам не нужно задавать этот заголовок, если только вам не нужно поддерживать старые версии браузера, что бывает очень редко.

      • Header set X-Frame-Options: "deny": предотвращение атак с использованием кликджекинга. Заголовок ‘X-Frame-Options’ говорит браузеру, может ли страница отображаться в <frame>, <iframe>, <embed> или <object>. Таким образом содержимое других сайтов не может быть встроено в другие сайты, что не позволяет выполнять атаки с использованием кликджекинга. Здесь вы запрещаете любое отображение во фрейме, чтобы веб-страница не могла быть встроена куда-либо еще, даже внутри одного веб-сайта. Вы можете изменить эту настройку согласно вашим потребностям, если, например, вам нужно разрешить отображение некоторых страниц, в частности, рекламных публикаций или взаимодействие с конкретными веб-сайтами.

      • Header set X-Content-Type-Options "nosniff": заголовок ‘X-Content-Type-Options’ контролирует типы MIME, запрещая их изменение или выполнение. Типы MIME — это стандарты формата файлов; они работают для текста, аудио, видео, изображений и т. д. Эти блоки заголовков не дают злоумышленникам получать информацию об этих файлах и пытаться изменить типы файлов.

      Перезапустите Apache для вступления изменений в силу:

      Чтобы проверить уровни безопасности ваших настроек конфигурации, откройте веб-сайт заголовков безопасности. После выполнения указаний данного руководства ваш домен должен получить оценку А.

      Примечание. Если в результате проверки заголовков на сайте https://securityheaders.com/ вы получили оценку F, причиной этому может быть отсутствие index.html внутри DocumentRoot вашего сайта, как указано в конце шага 2. Если в результате проверки вы получили любую оценку, кроме A и F, еще раз проверьте каждый набор заголовков на наличие опечаток, которые могли привести к снижению оценки.

      На этом шаге мы поработали с семью настройками для повышения безопасности заголовков и cookie-файлов. Эти действия помогут предотвратить межсайтовое выполнение сценариев, кликджекинг и другие типы атак.

      Заключение

      В этом обучающем руководстве мы изучили несколько аспектов безопасности, от раскрытия информации до защиты сеансов, задав альтернативные настройки конфигурации для важных с точки зрения безопасности функций.

      Дополнительную информацию о ресурсах или методах повышения безопасности Apache можно найти по этим ссылкам:

      Дополнительные инструменты для защиты Apache HTTP:

      • mod_evasive — полезный инструмент для смягчения последствий DoS-атак. Дополнительную информацию см. в статье Защита от DoS и DDoS с помощью mod_evasive в руководстве по работе с Apache.

      • fail2ban — это программное обеспечение для предотвращения повторных попыток входа в систему несанкционированных пользователей. Дополнительную информацию см. в руководстве Защита сервера Apache с помощью Fail2Ban.

      • ModSecurity — это брандмауэр веб-приложения (или WAF), который предоставляет широкий диапазон возможностей на основе предварительно заданных правил, написанный SpyderLabs и участниками сообщества. Дополнительную информацию об этом инструменте см. в руководстве Настройка ModSecurity в Apache.



      Source link