Before using MySQL Enterprise Firewall, install it according to the instructions provided in Section 8.4.7.2, “Installing or Uninstalling MySQL Enterprise Firewall”.
This section describes how to configure MySQL Enterprise Firewall using SQL statements. Alternatively, MySQL Workbench 6.3.4 or higher provides a graphical interface for firewall control. See MySQL Enterprise Firewall Interface.
          To enable or disable the firewall, set the
          mysql_firewall_mode system
          variable. By default, this variable is enabled when the
          firewall is installed. To control the initial firewall state
          explicitly, you can set the variable at server startup. For
          example, to enable the firewall in an option file, use these
          lines:
        
[mysqld]
mysql_firewall_mode=ON
          After modifying my.cnf, restart the
          server to cause the new setting to take effect.
        
Alternatively, to set and persist the firewall setting at runtime:
SET PERSIST mysql_firewall_mode = OFF;
SET PERSIST mysql_firewall_mode = ON;
          SET
          PERSIST sets a value for the running MySQL instance.
          It also saves the value, causing it to carry over to
          subsequent server restarts. To change a value for the running
          MySQL instance without having it carry over to subsequent
          restarts, use the GLOBAL keyword rather
          than PERSIST. See
          Section 15.7.6.1, “SET Syntax for Variable Assignment”.
          Each time the MYSQL_FIREWALL server-side
          plugin initializes, it loads data from these tables to its
          internal cache:
- firewall_whitelist
- firewall_group_allowlist
- firewall_users
- firewall_groups
- firewall_membership
          Without restarting the server or reinstalling the server-side
          plugin, modification of data outside of the plugin is not
          reflected internally. The
          mysql_firewall_reload_interval_seconds
          system variable makes it possible to force memory cache
          reloads from tables at specified intervals. By default, the
          periodic interval value is set to zero, which disables
          reloads.
        
          To schedule regular cache reloads, first ensure that the
          scheduler component is installed and
          enabled (see Section 7.5.5, “Scheduler Component”). To check
          the status of the component:
        
SHOW VARIABLES LIKE 'component_scheduler%';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------|
| component_scheduler.enabled | On    |
+-----------------------------+-------+
          With the firewall installed, set the
          mysql_firewall_reload_interval_seconds
          global system variable at server startup to a number between
          60 and the INT_MAX macro value of the platform hosting the
          server. Values between zero and 60 (1 through 59) reset to 60.
          For example:
        
$> mysqld [server-options] --mysql-firewall-reload-interval-seconds=40
...
2023-08-31T17:46:35.043468Z 0 [Warning] [MY-015031] [Server] Plugin MYSQL_FIREWALL 
reported: 'Invalid reload interval specified: 40. Valid values are 0 (off) or 
greater than or equal to 60. Adjusting to 60.'
...
          Alternatively, to set and persist the firewall setting at
          startup, precede the read-only variable name by the
          PERSIST_ONLY keyword or the
          @@PERSIST_ONLY. qualifier:
        
SET PERSIST_ONLY mysql_firewall_reload_interval_seconds = 120;
SET @@PERSIST_ONLY.mysql_firewall_reload_interval_seconds = 120;After modifying the variable, restart the server to cause the new setting to take effect.
With the firewall installed, grant the appropriate privileges to the MySQL account or accounts to be used for administering it. The privileges depend on which firewall operations an account should be permitted to perform:
- Grant the - FIREWALL_EXEMPTprivilege to any account that should be exempt from firewall restrictions. This is useful, for example, for a database administrator who configures the firewall, to avoid the possibility of a misconfiguration causing even the administrator to be locked out and unable to execute statements.
- Grant the - FIREWALL_ADMINprivilege to any account that should have full administrative firewall access. (Some administrative firewall functions can be invoked by accounts that have- FIREWALL_ADMINor the deprecated- SUPERprivilege, as indicated in the individual function descriptions.)
- Grant the - FIREWALL_USERprivilege to any account that should have administrative access only for its own firewall rules.
- Grant the - EXECUTEprivilege for the firewall stored procedures in the firewall database. These may invoke administrative functions, so stored procedure access also requires the privileges indicated earlier that are needed for those functions. The firewall database can be the- mysqlsystem database or a custom schema (see Installing MySQL Enterprise Firewall).
            The FIREWALL_EXEMPT,
            FIREWALL_ADMIN, and
            FIREWALL_USER privileges can
            be granted only while the firewall is installed because the
            MYSQL_FIREWALL plugin defines those
            privileges.
The MySQL server permits clients to connect and receives from them SQL statements to be executed. If the firewall is enabled, the server passes to it each incoming statement that does not immediately fail with a syntax error. Based on whether the firewall accepts the statement, the server executes it or returns an error to the client. This section describes how the firewall accomplishes the task of accepting or rejecting statements.
Firewall Profiles
The firewall uses a registry of profiles that determine whether to permit statement execution. Profiles have these attributes:
- An allowlist. The allowlist is the set of rules that defines which statements are acceptable to the profile. 
- A current operational mode. The mode enables the profile to be used in different ways. For example: the profile can be placed in training mode to establish the allowlist; the allowlist can be used for restricting statement execution or intrusion detection; the profile can be disabled entirely. 
- A scope of applicability. The scope indicates which client connections the profile applies to: - The firewall supports account-based profiles such that each profile matches a particular client account (client user name and host name combination). For example, you can register one account profile for which the allowlist applies to connections originating from - admin@localhostand another account profile for which the allowlist applies to connections originating from- myapp@apphost.example.com.
- The firewall supports group profiles that can have multiple accounts as members, with the profile allowlist applying equally to all members. Group profiles enable easier administration and greater flexibility for deployments that require applying a given set of allowlist rules to multiple accounts. 
 
Initially, no profiles exist, so by default, the firewall accepts all statements and has no effect on which statements MySQL accounts can execute. To apply firewall protective capabilities, explicit action is required:
- Register one or more profiles with the firewall. 
- Train the firewall by establishing the allowlist for each profile; that is, the types of statements the profile permits clients to execute. 
- Place the trained profiles in protecting mode to harden MySQL against unauthorized statement execution: - MySQL associates each client session with a specific user name and host name combination. This combination is the session account. 
- For each client connection, the firewall uses the session account to determine which profiles apply to handling incoming statements from the client. - The firewall accepts only statements permitted by the applicable profile allowlists. 
 
Most firewall principles apply identically to group profiles and account profiles. The two types of profiles differ in these respects:
- An account profile allowlist applies only to a single account. A group profile allowlist applies when the session account matches any account that is a member of the group. 
- To apply an allowlist to multiple accounts using account profiles, it is necessary to register one profile per account and duplicate the allowlist across each profile. This entails training each account profile individually because each one must be trained using the single account to which it applies. - A group profile allowlist applies to multiple accounts, with no need to duplicate it for each account. A group profile can be trained using any or all of the group member accounts, or training can be limited to any single member. Either way, the allowlist applies to all members. 
- Account profile names are based on specific user name and host name combinations that depend on which clients connect to the MySQL server. Group profile names are chosen by the firewall administrator with no constraints other than that their length must be from 1 to 288 characters. 
Due to the advantages of group profiles over account profiles, and because a group profile with a single member account is logically equivalent to an account profile for that account, it is recommended that all new firewall profiles be created as group profiles. Account profiles are deprecated, and subject to removal in a future MySQL version. For assistance converting existing account profiles, see Migrating Account Profiles to Group Profiles.
The profile-based protection afforded by the firewall enables implementation of strategies such as these:
- If an application has unique protection requirements, configure it to use an account not used for any other purpose and set up a group profile or account profile for that account. 
- If related applications share protection requirements, associate each application with its own account, then add these application accounts as members of the same group profile. Alternatively, configure all the applications to use the same account and associate them with an account profile for that account. 
Firewall Statement Matching
Statement matching performed by the firewall does not use SQL statements as received from clients. Instead, the server converts incoming statements to normalized digest form and firewall operation uses these digests. The benefit of statement normalization is that it enables similar statements to be grouped and recognized using a single pattern. For example, these statements are distinct from each other:
SELECT first_name, last_name FROM customer WHERE customer_id = 1;
select first_name, last_name from customer where customer_id = 99;
SELECT first_name, last_name FROM customer WHERE customer_id = 143;But all of them have the same normalized digest form:
SELECT `first_name` , `last_name` FROM `customer` WHERE `customer_id` = ?By using normalization, firewall allowlists can store digests that each match many different statements received from clients. For more information about normalization and digests, see Section 29.10, “Performance Schema Statement Digests and Sampling”.
            Setting the
            max_digest_length system
            variable to zero disables digest production, which also
            disables server functionality that requires digests, such as
            MySQL Enterprise Firewall.
Profile Operational Modes
Each profile registered with the firewall has its own operational mode, chosen from these values:
- OFF: This mode disables the profile. The firewall considers it inactive and ignores it.
- RECORDING: This is the firewall training mode. Incoming statements received from a client that matches the profile are considered acceptable for the profile and become part of its “fingerprint.” The firewall records the normalized digest form of each statement to learn the acceptable statement patterns for the profile. Each pattern is a rule, and the union of the rules is the profile allowlist.- A difference between group and account profiles is that statement recording for a group profile can be limited to statements received from a single group member (the training member). 
- PROTECTING: In this mode, the profile allows or prevents statement execution. The firewall matches incoming statements against the profile allowlist, accepting only statements that match and rejecting those that do not. After training a profile in- RECORDINGmode, switch it to- PROTECTINGmode to harden MySQL against access by statements that deviate from the allowlist. If the- mysql_firewall_tracesystem variable is enabled, the firewall also writes rejected statements to the error log.
- DETECTING: This mode detects but not does not block intrusions (statements that are suspicious because they match nothing in the profile allowlist). In- DETECTINGmode, the firewall writes suspicious statements to the error log but accepts them without denying access.
          When a profile is assigned any of the preceding mode values,
          the firewall stores the mode in the profile. Firewall
          mode-setting operations also permit a mode value of
          RESET, but this value is not stored:
          setting a profile to RESET mode causes the
          firewall to delete all rules for the profile and set its mode
          to OFF.
            Messages written to the error log in
            DETECTING mode or because
            mysql_firewall_trace is
            enabled are written as Notes, which are information
            messages. To ensure that such messages appear in the error
            log and are not discarded, make sure that error-logging
            verbosity is sufficient to include information messages. For
            example, if you are using priority-based log filtering, as
            described in
            Section 7.4.2.5, “Priority-Based Error Log Filtering (log_filter_internal)”, set
            the log_error_verbosity
            system variable to a value of 3.
Firewall Statement Handling When Multiple Profiles Apply
For simplicity, later sections that describe how to set up profiles take the perspective that the firewall matches incoming statements from a client against only a single profile, either a group profile or account profile. But firewall operation can be more complex:
- A group profile can include multiple accounts as members. 
- An account can be a member of multiple group profiles. 
- Multiple profiles can match a given client. 
The following description covers the general case of how the firewall operates, when potentially multiple profiles apply to incoming statements.
As previously mentioned, MySQL associates each client session with a specific user name and host name combination known as the session account. The firewall matches the session account against registered profiles to determine which profiles apply to handling incoming statements from the session:
- The firewall ignores inactive profiles (profiles with a mode of - OFF).
- The session account matches every active group profile that includes a member having the same user and host. There can be more than one such group profile. 
- The session account matches an active account profile having the same user and host, if there is one. There is at most one such account profile. 
In other words, the session account can match 0 or more active group profiles, and 0 or 1 active account profiles. This means that 0, 1, or multiple firewall profiles are applicable to a given session, for which the firewall handles each incoming statement as follows:
- If there is no applicable profile, the firewall imposes no restrictions and accepts the statement. 
- If there are applicable profiles, their modes determine statement handling: - The firewall records the statement in the allowlist of each applicable profile that is in - RECORDINGmode.
- The firewall writes the statement to the error log for each applicable profile in - DETECTINGmode for which the statement is suspicious (does not match the profile allowlist).
- The firewall accepts the statement if at least one applicable profile is in - RECORDINGor- DETECTINGmode (those modes accept all statements), or if the statement matches the allowlist of at least one applicable profile in- PROTECTINGmode. Otherwise, the firewall rejects the statement (and writes it to the error log if the- mysql_firewall_tracesystem variable is enabled).
 
With that description in mind, the next sections revert to the simplicity of the situations when a single group profile or a single account profile apply, and cover how to set up each type of profile.
MySQL Enterprise Firewall supports registration of group profiles. A group profile can have multiple accounts as its members. To use a firewall group profile to protect MySQL against incoming statements from a given account, follow these steps:
- Register the group profile and put it in - RECORDINGmode.
- Add a member account to the group profile. 
- Connect to the MySQL server using the member account and execute statements to be learned. This trains the group profile and establishes the rules that form the profile allowlist. 
- Add to the group profile any other accounts that are to be group members. 
- Switch the group profile to - PROTECTINGmode. When a client connects to the server using any account that is a member of the group profile, the profile allowlist restricts statement execution.
- Should additional training be necessary, switch the group profile to - RECORDINGmode again, update its allowlist with new statement patterns, then switch it back to- PROTECTINGmode.
Observe these guidelines for firewall-related account references:
- Take note of the context in which account references occur. To name an account for firewall operations, specify it as a single quoted string ( - '). This differs from the usual MySQL convention for statements such as- user_name@- host_name'- CREATE USERand- GRANT, for which you quote the user and host parts of an account name separately (- ').- user_name'@'- host_name'- The requirement for naming accounts as a single quoted string for firewall operations means that you cannot use accounts that have embedded - @characters in the user name.
- The firewall assesses statements against accounts represented by actual user and host names as authenticated by the server. When registering accounts in profiles, do not use wildcard characters or netmasks: - Suppose that an account named - me@%.example.orgexists and a client uses it to connect to the server from the host- abc.example.org.
- The account name contains a - %wildcard character, but the server authenticates the client as having a user name of- meand host name of- abc.example.com, and that is what the firewall sees.
- Consequently, the account name to use for firewall operations is - me@abc.example.orgrather than- me@%.example.org.
 
          The following procedure shows how to register a group profile
          with the firewall, train the firewall to know the acceptable
          statements for that profile (its allowlist), use the profile
          to protect MySQL against execution of unacceptable statements,
          and add and remove group members. The example uses a group
          profile name of fwgrp. The example profile
          is presumed for use by clients of an application that accesses
          tables in the sakila database (available at
          https://dev.mysql.com/doc/index-other.html).
        
          Use an administrative MySQL account to perform the steps in
          this procedure, except those steps designated for execution by
          member accounts of the firewall group profile. For statements
          executed by member accounts, the default database should be
          sakila. (You can use a different database
          by adjusting the instructions accordingly.)
- If necessary, create the accounts that are to be members of the - fwgrpgroup profile and grant them appropriate access privileges. Statements for one member are shown here (choose an appropriate password):- CREATE USER 'member1'@'localhost' IDENTIFIED BY 'password'; GRANT ALL ON sakila.* TO 'member1'@'localhost';
- Use the - sp_set_firewall_group_mode()stored procedure to register the group profile with the firewall and place the profile in- RECORDING(training) mode:- CALL mysql.sp_set_firewall_group_mode('fwgrp', 'RECORDING');Note- If you have installed MySQL Enterprise Firewall in a custom schema, then make appropriate substitution for your system. For example, if the firewall is installed in the - fwdbschema, then execute the stored procedures like this:- CALL fwdb.sp_set_firewall_group_mode('fwgrp', 'RECORDING');
- Use the - sp_firewall_group_enlist()stored procedure to add an initial member account for use in training the group profile allowlist:- CALL mysql.sp_firewall_group_enlist('fwgrp', 'member1@localhost');
- To train the group profile using the initial member account, connect to the server as - member1from the server host so that the firewall sees a session account of- member1@localhost. Then execute some statements to be considered legitimate for the profile. For example:- SELECT title, release_year FROM film WHERE film_id = 1; UPDATE actor SET last_update = NOW() WHERE actor_id = 1; SELECT store_id, COUNT(*) FROM inventory GROUP BY store_id;- The firewall receives the statements from the - member1@localhostaccount. Because that account is a member of the- fwgrpprofile, which is in- RECORDINGmode, the firewall interprets the statements as applicable to- fwgrpand records the normalized digest form of the statements as rules in the- fwgrpallowlist. Those rules then apply to all accounts that are members of- fwgrp.Note- Until the - fwgrpgroup profile receives statements in- RECORDINGmode, its allowlist is empty, which is equivalent to “deny all.” No statement can match an empty allowlist, which has these implications:- The group profile cannot be switched to - PROTECTINGmode. It would reject every statement, effectively prohibiting the accounts that are group members from executing any statement.
- The group profile can be switched to - DETECTINGmode. In this case, the profile accepts every statement but logs it as suspicious.
 
- At this point, the group profile information is cached, including its name, membership, and allowlist. To see this information, query the Performance Schema firewall tables: - mysql> SELECT MODE FROM performance_schema.firewall_groups WHERE NAME = 'fwgrp'; +-----------+ | MODE | +-----------+ | RECORDING | +-----------+ mysql> SELECT * FROM performance_schema.firewall_membership WHERE GROUP_ID = 'fwgrp' ORDER BY MEMBER_ID; +----------+-------------------+ | GROUP_ID | MEMBER_ID | +----------+-------------------+ | fwgrp | member1@localhost | +----------+-------------------+ mysql> SELECT RULE FROM performance_schema.firewall_group_allowlist WHERE NAME = 'fwgrp'; +----------------------------------------------------------------------+ | RULE | +----------------------------------------------------------------------+ | SELECT @@`version_comment` LIMIT ? | | UPDATE `actor` SET `last_update` = NOW ( ) WHERE `actor_id` = ? | | SELECT `title` , `release_year` FROM `film` WHERE `film_id` = ? | | SELECT `store_id` , COUNT ( * ) FROM `inventory` GROUP BY `store_id` | +----------------------------------------------------------------------+Note- The - @@version_commentrule comes from a statement sent automatically by the mysql client when you connect to the server.Important- Train the firewall under conditions matching application use. For example, to determine server characteristics and capabilities, a given MySQL connector might send statements to the server at the beginning of each session. If an application normally is used through that connector, train the firewall using the connector, too. That enables those initial statements to become part of the allowlist for the group profile associated with the application. 
- Invoke - sp_set_firewall_group_mode()again to switch the group profile to- PROTECTINGmode:- CALL mysql.sp_set_firewall_group_mode('fwgrp', 'PROTECTING');Important- Switching the group profile out of - RECORDINGmode synchronizes its cached data to the firewall database tables that provide persistent underlying storage. If you do not switch the mode for a profile that is being recorded, the cached data is not written to persistent storage and is lost when the server is restarted. The firewall database can be the- mysqlsystem database or a custom schema (see Installing MySQL Enterprise Firewall).
- Add to the group profile any other accounts that should be members: - CALL mysql.sp_firewall_group_enlist('fwgrp', 'member2@localhost'); CALL mysql.sp_firewall_group_enlist('fwgrp', 'member3@localhost'); CALL mysql.sp_firewall_group_enlist('fwgrp', 'member4@localhost');- The profile allowlist trained using the - member1@localhostaccount now also applies to the additional accounts.
- To verify the updated group membership, query the - firewall_membershiptable again:- mysql> SELECT * FROM performance_schema.firewall_membership WHERE GROUP_ID = 'fwgrp' ORDER BY MEMBER_ID; +----------+-------------------+ | GROUP_ID | MEMBER_ID | +----------+-------------------+ | fwgrp | member1@localhost | | fwgrp | member2@localhost | | fwgrp | member3@localhost | | fwgrp | member4@localhost | +----------+-------------------+
- Test the group profile against the firewall by using any account in the group to execute some acceptable and unacceptable statements. The firewall matches each statement from the account against the profile allowlist and accepts or rejects it: - This statement is not identical to a training statement but produces the same normalized statement as one of them, so the firewall accepts it: - mysql> SELECT title, release_year FROM film WHERE film_id = 98; +-------------------+--------------+ | title | release_year | +-------------------+--------------+ | BRIGHT ENCOUNTERS | 2006 | +-------------------+--------------+
- These statements match nothing in the allowlist, so the firewall rejects each with an error: - mysql> SELECT title, release_year FROM film WHERE film_id = 98 OR TRUE; ERROR 1045 (28000): Statement was blocked by Firewall mysql> SHOW TABLES LIKE 'customer%'; ERROR 1045 (28000): Statement was blocked by Firewall mysql> TRUNCATE TABLE mysql.slow_log; ERROR 1045 (28000): Statement was blocked by Firewall
- If the - mysql_firewall_tracesystem variable is enabled, the firewall also writes rejected statements to the error log. For example:- [Note] Plugin MYSQL_FIREWALL reported: 'ACCESS DENIED for 'member1@localhost'. Reason: No match in allowlist. Statement: TRUNCATE TABLE `mysql` . `slow_log`'- These log messages may be helpful in identifying the source of attacks, should that be necessary. 
 
- Should members need to be removed from the group profile, use the - sp_firewall_group_delist()stored procedure rather than- sp_firewall_group_enlist():- CALL mysql.sp_firewall_group_delist('fwgrp', 'member3@localhost');
The firewall group profile now is trained for member accounts. When clients connect using any account in the group and attempt to execute statements, the profile protects MySQL against statements not matched by the profile allowlist.
          The procedure just shown added only one member to the group
          profile before training its allowlist. Doing so provides
          better control over the training period by limiting which
          accounts can add new acceptable statements to the allowlist.
          Should additional training be necessary, you can switch the
          profile back to RECORDING mode:
        
CALL mysql.sp_set_firewall_group_mode('fwgrp', 'RECORDING');
          However, that enables any member of the group to execute
          statements and add them to the allowlist. To limit the
          additional training to a single group member, call
          sp_set_firewall_group_mode_and_user(),
          which is like sp_set_firewall_group_mode()
          but takes one more argument specifying which account is
          permitted to train the profile in RECORDING
          mode. For example, to enable training only by
          member4@localhost, do this:
        
CALL mysql.sp_set_firewall_group_mode_and_user('fwgrp', 'RECORDING', 'member4@localhost');
          That enables additional training by the specified account
          without having to remove the other group members. They can
          execute statements, but the statements are not added to the
          allowlist. (Remember, however, that in
          RECORDING mode the other members can
          execute any statement.)
To avoid unexpected behavior when a particular account is specified as the training account for a group profile, always ensure that account is a member of the group.
          After the additional training, set the group profile back to
          PROTECTING mode:
        
CALL mysql.sp_set_firewall_group_mode('fwgrp', 'PROTECTING');
          The training account established by
          sp_set_firewall_group_mode_and_user() is
          saved in the group profile, so the firewall remembers it in
          case more training is needed later. Thus, if you call
          sp_set_firewall_group_mode() (which takes
          no training account argument), the current profile training
          account, member4@localhost, remains
          unchanged.
        
          To clear the training account if it actually is desired to
          enable all group members to perform training in
          RECORDING mode, call
          sp_set_firewall_group_mode_and_user() and
          pass a NULL value for the account argument:
        
CALL mysql.sp_set_firewall_group_mode_and_user('fwgrp', 'RECORDING', NULL);
          It is possible to detect intrusions by logging nonmatching
          statements as suspicious without denying access. First, put
          the group profile in DETECTING mode:
        
CALL mysql.sp_set_firewall_group_mode('fwgrp', 'DETECTING');
          Then, using a member account, execute a statement that does
          not match the group profile allowlist. In
          DETECTING mode, the firewall permits the
          nonmatching statement to execute:
        
mysql> SHOW TABLES LIKE 'customer%';
+------------------------------+
| Tables_in_sakila (customer%) |
+------------------------------+
| customer                     |
| customer_list                |
+------------------------------+In addition, the firewall writes a message to the error log:
[Note] Plugin MYSQL_FIREWALL reported:
'SUSPICIOUS STATEMENT from 'member1@localhost'. Reason: No match in allowlist.
Statement: SHOW TABLES LIKE ?'
          To disable a group profile, change its mode to
          OFF:
        
CALL mysql.sp_set_firewall_group_mode(group, 'OFF');To forget all training for a profile and disable it, reset it:
CALL mysql.sp_set_firewall_group_mode(group, 'RESET');
          The reset operation causes the firewall to delete all rules
          for the profile and set its mode to OFF.
MySQL Enterprise Firewall enables profiles to be registered that correspond to individual accounts. To use a firewall account profile to protect MySQL against incoming statements from a given account, follow these steps:
- Register the account profile and put it in - RECORDINGmode.
- Connect to the MySQL server using the account and execute statements to be learned. This trains the account profile and establishes the rules that form the profile allowlist. 
- Switch the account profile to - PROTECTINGmode. When a client connects to the server using the account, the account profile allowlist restricts statement execution.
- Should additional training be necessary, switch the account profile to - RECORDINGmode again, update its allowlist with new statement patterns, then switch it back to- PROTECTINGmode.
Observe these guidelines for firewall-related account references:
- Take note of the context in which account references occur. To name an account for firewall operations, specify it as a single quoted string ( - '). This differs from the usual MySQL convention for statements such as- user_name@- host_name'- CREATE USERand- GRANT, for which you quote the user and host parts of an account name separately (- ').- user_name'@'- host_name'- The requirement for naming accounts as a single quoted string for firewall operations means that you cannot use accounts that have embedded - @characters in the user name.
- The firewall assesses statements against accounts represented by actual user and host names as authenticated by the server. When registering accounts in profiles, do not use wildcard characters or netmasks: - Suppose that an account named - me@%.example.orgexists and a client uses it to connect to the server from the host- abc.example.org.
- The account name contains a - %wildcard character, but the server authenticates the client as having a user name of- meand host name of- abc.example.com, and that is what the firewall sees.
- Consequently, the account name to use for firewall operations is - me@abc.example.orgrather than- me@%.example.org.
 
          The following procedure shows how to register an account
          profile with the firewall, train the firewall to know the
          acceptable statements for that profile (its allowlist), and
          use the profile to protect MySQL against execution of
          unacceptable statements by the account. The example account,
          fwuser@localhost, is presumed for use by an
          application that accesses tables in the
          sakila database (available at
          https://dev.mysql.com/doc/index-other.html).
        
          Use an administrative MySQL account to perform the steps in
          this procedure, except those steps designated for execution by
          the fwuser@localhost account that
          corresponds to the account profile registered with the
          firewall. For statements executed using this account, the
          default database should be sakila. (You can
          use a different database by adjusting the instructions
          accordingly.)
- If necessary, create the account to use for executing statements (choose an appropriate password) and grant it privileges for the - sakiladatabase:- CREATE USER 'fwuser'@'localhost' IDENTIFIED BY 'password'; GRANT ALL ON sakila.* TO 'fwuser'@'localhost';
- Use the - sp_set_firewall_mode()stored procedure to register the account profile with the firewall and place the profile in- RECORDING(training) mode:- CALL mysql.sp_set_firewall_mode('fwuser@localhost', 'RECORDING');Note- If you have installed MySQL Enterprise Firewall in a custom schema, then make appropriate substitution for your system. For example, if the firewall is installed in the - fwdbschema, then execute the stored procedures like this:- CALL fwdb.sp_set_firewall_mode('fwuser@localhost', 'RECORDING');
- To train the registered account profile, connect to the server as - fwuserfrom the server host so that the firewall sees a session account of- fwuser@localhost. Then use the account to execute some statements to be considered legitimate for the profile. For example:- SELECT first_name, last_name FROM customer WHERE customer_id = 1; UPDATE rental SET return_date = NOW() WHERE rental_id = 1; SELECT get_customer_balance(1, NOW());- Because the profile is in - RECORDINGmode, the firewall records the normalized digest form of the statements as rules in the profile allowlist.Note- Until the - fwuser@localhostaccount profile receives statements in- RECORDINGmode, its allowlist is empty, which is equivalent to “deny all.” No statement can match an empty allowlist, which has these implications:- The account profile cannot be switched to - PROTECTINGmode. It would reject every statement, effectively prohibiting the account from executing any statement.
- The account profile can be switched to - DETECTINGmode. In this case, the profile accepts every statement but logs it as suspicious.
 
- At this point, the account profile information is cached. To see this information, query the - INFORMATION_SCHEMAfirewall tables:- mysql> SELECT MODE FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_USERS WHERE USERHOST = 'fwuser@localhost'; +-----------+ | MODE | +-----------+ | RECORDING | +-----------+ mysql> SELECT RULE FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_WHITELIST WHERE USERHOST = 'fwuser@localhost'; +----------------------------------------------------------------------------+ | RULE | +----------------------------------------------------------------------------+ | SELECT `first_name` , `last_name` FROM `customer` WHERE `customer_id` = ? | | SELECT `get_customer_balance` ( ? , NOW ( ) ) | | UPDATE `rental` SET `return_date` = NOW ( ) WHERE `rental_id` = ? | | SELECT @@`version_comment` LIMIT ? | +----------------------------------------------------------------------------+Note- The - @@version_commentrule comes from a statement sent automatically by the mysql client when you connect to the server.Important- Train the firewall under conditions matching application use. For example, to determine server characteristics and capabilities, a given MySQL connector might send statements to the server at the beginning of each session. If an application normally is used through that connector, train the firewall using the connector, too. That enables those initial statements to become part of the allowlist for the account profile associated with the application. 
- Invoke - sp_set_firewall_mode()again, this time switching the account profile to- PROTECTINGmode:- CALL mysql.sp_set_firewall_mode('fwuser@localhost', 'PROTECTING');Important- Switching the account profile out of - RECORDINGmode synchronizes its cached data to the firewall database tables that provide persistent underlying storage. If you do not switch the mode for a profile that is being recorded, the cached data is not written to persistent storage and is lost when the server is restarted. The firewall database can be the- mysqlsystem database or a custom schema (see Installing MySQL Enterprise Firewall).
- Test the account profile by using the account to execute some acceptable and unacceptable statements. The firewall matches each statement from the account against the profile allowlist and accepts or rejects it: - This statement is not identical to a training statement but produces the same normalized statement as one of them, so the firewall accepts it: - mysql> SELECT first_name, last_name FROM customer WHERE customer_id = '48'; +------------+-----------+ | first_name | last_name | +------------+-----------+ | ANN | EVANS | +------------+-----------+
- These statements match nothing in the allowlist, so the firewall rejects each with an error: - mysql> SELECT first_name, last_name FROM customer WHERE customer_id = 1 OR TRUE; ERROR 1045 (28000): Statement was blocked by Firewall mysql> SHOW TABLES LIKE 'customer%'; ERROR 1045 (28000): Statement was blocked by Firewall mysql> TRUNCATE TABLE mysql.slow_log; ERROR 1045 (28000): Statement was blocked by Firewall
- If the - mysql_firewall_tracesystem variable is enabled, the firewall also writes rejected statements to the error log. For example:- [Note] Plugin MYSQL_FIREWALL reported: 'ACCESS DENIED for fwuser@localhost. Reason: No match in allowlist. Statement: TRUNCATE TABLE `mysql` . `slow_log`'- These log messages may be helpful in identifying the source of attacks, should that be necessary. 
 
          The firewall account profile now is trained for the
          fwuser@localhost account. When clients
          connect using that account and attempt to execute statements,
          the profile protects MySQL against statements not matched by
          the profile allowlist.
        
          It is possible to detect intrusions by logging nonmatching
          statements as suspicious without denying access. First, put
          the account profile in DETECTING mode:
        
CALL mysql.sp_set_firewall_mode('fwuser@localhost', 'DETECTING');
          Then, using the account, execute a statement that does not
          match the account profile allowlist. In
          DETECTING mode, the firewall permits the
          nonmatching statement to execute:
        
mysql> SHOW TABLES LIKE 'customer%';
+------------------------------+
| Tables_in_sakila (customer%) |
+------------------------------+
| customer                     |
| customer_list                |
+------------------------------+In addition, the firewall writes a message to the error log:
[Note] Plugin MYSQL_FIREWALL reported:
'SUSPICIOUS STATEMENT from 'fwuser@localhost'. Reason: No match in allowlist.
Statement: SHOW TABLES LIKE ?'
          To disable an account profile, change its mode to
          OFF:
        
CALL mysql.sp_set_firewall_mode(user, 'OFF');To forget all training for a profile and disable it, reset it:
CALL mysql.sp_set_firewall_mode(user, 'RESET');
          The reset operation causes the firewall to delete all rules
          for the profile and set its mode to OFF.
          To assess firewall activity, examine its status variables. For
          example, after performing the procedure shown earlier to train
          and protect the fwgrp group profile, the
          variables look like this:
        
mysql> SHOW GLOBAL STATUS LIKE 'Firewall%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Firewall_access_denied     | 3     |
| Firewall_access_granted    | 4     |
| Firewall_access_suspicious | 1     |
| Firewall_cached_entries    | 4     |
+----------------------------+-------+
          The variables indicate the number of statements rejected,
          accepted, logged as suspicious, and added to the cache,
          respectively. The
          Firewall_access_granted
          count is 4 because of the @@version_comment
          statement sent by the mysql client each of
          the three times you connected using the registered account,
          plus the SHOW TABLES statement
          that was not blocked in DETECTING mode.
MySQL Enterprise Firewall supports account profiles that each apply to a single account and also group profiles that each can apply to multiple accounts. A group profile enables easier administration when the same allowlist is to be applied to multiple accounts: instead of creating one account profile per account and duplicating the allowlist across all those profiles, create a single group profile and make the accounts members of it. The group allowlist then applies to all the accounts.
A group profile with a single member account is logically equivalent to an account profile for that account, so it is possible to administer the firewall using group profiles exclusively, rather than a mix of account and group profiles. For new firewall installations, that is accomplished by uniformly creating new profiles as group profiles and avoiding account profiles.
          Due to the greater flexibility offered by group profiles, it
          is recommended that all new firewall profiles be created as
          group profiles. Account profiles are deprecated, and subject
          to removal in a future MySQL version. For upgrades from
          firewall installations that already contain account profiles,
          MySQL Enterprise Firewall includes a stored procedure named
          sp_migrate_firewall_user_to_group() to help
          you convert account profiles to group profiles. To use it,
          perform the following procedure as a user who has the
          FIREWALL_ADMIN privilege:
- Run the - firewall_profile_migration.sqlscript to install the- sp_migrate_firewall_user_to_group()stored procedure. The script is located in the- sharedirectory of your MySQL installation.- Specify the same firewall database name on the command line that you previously defined for your firewall installation. The example here specifies the system database, - mysql.- $> mysql -u root -p -D mysql < firewall_profile_migration.sql Enter password: (enter root password here)- If you installed MySQL Enterprise Firewall in a custom schema, make the appropriate substitution for your system. 
- Identify which account profiles exist by querying the Information Schema - MYSQL_FIREWALL_USERStable. For example:- mysql> SELECT USERHOST FROM INFORMATION_SCHEMA.MYSQL_FIREWALL_USERS; +-------------------------------+ | USERHOST | +-------------------------------+ | admin@localhost | | local_client@localhost | | remote_client@abc.example.com | +-------------------------------+
- For each account profile identified by the previous step, convert it to a group profile. Replace the - mysql.prefix with the actual firewall database name, if necessary:- CALL mysql.sp_migrate_firewall_user_to_group('admin@localhost', 'admins'); CALL mysql.sp_migrate_firewall_user_to_group('local_client@localhost', 'local_clients'); CALL mysql.sp_migrate_firewall_user_to_group('remote_client@localhost', 'remote_clients');- In each case, the account profile must exist and must not currently be in - RECORDINGmode, and the group profile must not already exist. The resulting group profile has the named account as its single enlisted member, which is also set as the group training account. The group profile operational mode is taken from the account profile operational mode.
- (Optional) Remove - sp_migrate_firewall_user_to_group():- DROP PROCEDURE IF EXISTS mysql.sp_migrate_firewall_user_to_group;- If you installed MySQL Enterprise Firewall in a custom schema, make the appropriate substitution for your system. 
          For additional details about
          sp_migrate_firewall_user_to_group(), see
          Firewall Miscellaneous Stored Procedures.