mirror of
https://gitlab.com/shorewall/code.git
synced 2024-12-22 22:30:58 +01:00
5338cb48b0
git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@1070 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
569 lines
20 KiB
Plaintext
Executable File
569 lines
20 KiB
Plaintext
Executable File
##############################################################################
|
|
# /etc/shorewall/shorewall.conf V1.4 - Change the following variables to
|
|
# match your setup
|
|
#
|
|
# This program is under GPL [http://www.gnu.org/copyleft/gpl.htm]
|
|
#
|
|
# This file should be placed in /etc/shorewall
|
|
#
|
|
# (c) 1999,2000,2001,2002,2003 - Tom Eastep (teastep@shorewall.net)
|
|
##############################################################################
|
|
# L O G G I N G
|
|
##############################################################################
|
|
#
|
|
# General note about log levels. Log levels are a method of describing
|
|
# to syslog (8) the importance of a message and a number of parameters
|
|
# in this file have log levels as their value.
|
|
#
|
|
# Valid levels are:
|
|
#
|
|
# 7 debug
|
|
# 6 info
|
|
# 5 notice
|
|
# 4 warning
|
|
# 3 err
|
|
# 2 crit
|
|
# 1 alert
|
|
# 0 emerg
|
|
#
|
|
# For most Shorewall logging, a level of 6 (info) is appropriate. Shorewall
|
|
# log messages are generated by NetFilter and are logged using facility
|
|
# 'kern' and the level that you specifify. If you are unsure of the level
|
|
# to choose, 6 (info) is a safe bet. You may specify levels by name or by
|
|
# number.
|
|
#
|
|
# If you have build your kernel with ULOG target support, you may also
|
|
# specify a log level of ULOG (must be all caps). Rather than log its
|
|
# messages to syslogd, Shorewall will direct netfilter to log the messages
|
|
# via the ULOG target which will send them to a process called 'ulogd'.
|
|
# ulogd is available from http://www.gnumonks.org/projects/ulogd and can be
|
|
# configured to log all Shorewall message to their own log file
|
|
################################################################################
|
|
#
|
|
# LOG FILE LOCATION
|
|
#
|
|
# This variable tells the /sbin/shorewall program where to look for Shorewall
|
|
# log messages. If not set or set to an empty string (e.g., LOGFILE="") then
|
|
# /var/log/messages is assumed.
|
|
#
|
|
# WARNING: The LOGFILE variable simply tells the 'shorewall' program where to
|
|
# look for Shorewall messages.It does NOT control the destination for
|
|
# these messages. For information about how to do that, see
|
|
#
|
|
# http://www.shorewall.net/shorewall_logging.html
|
|
|
|
LOGFILE=/var/log/messages
|
|
|
|
#
|
|
# LOG FORMAT
|
|
#
|
|
# Shell 'printf' Formatting template for the --log-prefix value in log messages
|
|
# generated by Shorewall to identify Shorewall log messages. The supplied
|
|
# template is expected to accept either two or three arguments; the first is
|
|
# the chain name, the second (optional) is the logging rule number within that
|
|
# chain and the third is the ACTION specifying the disposition of the packet
|
|
# being logged. You must use the %d formatting type for the rule number; if your
|
|
# template does not contain %d then the rule number will not be included.
|
|
#
|
|
# If you want to integrate Shorewall with fireparse, then set LOGFORMAT as:
|
|
#
|
|
# LOGFORMAT="fp=%s:%d a=%s "
|
|
#
|
|
# If not specified or specified as empty (LOGFORMAT="") then the value
|
|
# "Shorewall:%s:%s:" is assumed.
|
|
#
|
|
# CAUTION: /sbin/shorewall uses the leading part of the LOGFORMAT string (up
|
|
# to but not including the first '%') to find log messages in the 'show log',
|
|
# 'status' and 'hits' commands. This part should not be omitted (the
|
|
# LOGFORMAT should not begin with "%") and the leading part should be
|
|
# sufficiently unique for /sbin/shorewall to identify Shorewall messages.
|
|
|
|
LOGFORMAT="Shorewall:%s:%s:"
|
|
|
|
#
|
|
# LOG RATE LIMITING
|
|
#
|
|
# The next two variables can be used to control the amount of log output
|
|
# generated. LOGRATE is expressed as a number followed by an optional
|
|
# `/second', `/minute', `/hour', or `/day' suffix and specifies the maximum
|
|
# rate at which a particular message will occur. LOGBURST determines the
|
|
# maximum initial burst size that will be logged. If set empty, the default
|
|
# value of 5 will be used.
|
|
#
|
|
# Example:
|
|
#
|
|
# LOGRATE=10/minute
|
|
# LOGBURST=5
|
|
#
|
|
# If BOTH variables are set empty then logging will not be rate-limited.
|
|
#
|
|
|
|
LOGRATE=
|
|
LOGBURST=
|
|
|
|
#
|
|
# LEVEL AT WHICH TO LOG 'UNCLEAN' PACKETS
|
|
#
|
|
# This variable determines the level at which Mangled/Invalid packets are logged
|
|
# under the 'dropunclean' interface option. If you set this variable to an
|
|
# empty value (e.g., LOGUNCLEAN= ), Mangled/Invalid packets will be dropped
|
|
# silently.
|
|
#
|
|
# The value of this variable also determines the level at which Mangled/Invalid
|
|
# packets are logged under the 'logunclean' interface option. If the variable
|
|
# is empty, these packets will still be logged at the 'info' level.
|
|
#
|
|
# See the comment at the top of this section for a description of log levels
|
|
#
|
|
|
|
LOGUNCLEAN=info
|
|
|
|
#
|
|
# BLACKLIST LOG LEVEL
|
|
#
|
|
# Set this variable to the syslogd level that you want blacklist packets logged
|
|
# (beware of DOS attacks resulting from such logging). If not set, no logging
|
|
# of blacklist packets occurs.
|
|
#
|
|
# See the comment at the top of this section for a description of log levels
|
|
#
|
|
BLACKLIST_LOGLEVEL=
|
|
|
|
#
|
|
# LOGGING 'New not SYN' rejects
|
|
#
|
|
# This variable only has an effect when NEWNOTSYN=No (see below).
|
|
#
|
|
# When a TCP packet that does not have the SYN flag set and the ACK and RST
|
|
# flags clear then unless the packet is part of an established connection,
|
|
# it will be rejected by the firewall. If you want these rejects logged,
|
|
# then set LOGNEWNOTSYN to the syslog log level at which you want them logged.
|
|
#
|
|
# See the comment at the top of this section for a description of log levels
|
|
#
|
|
# Example: LOGNEWNOTSYN=debug
|
|
|
|
|
|
LOGNEWNOTSYN=info
|
|
|
|
#
|
|
# MAC List Log Level
|
|
#
|
|
# Specifies the logging level for connection requests that fail MAC
|
|
# verification. If set to the empty value (MACLIST_LOG_LEVEL="") then
|
|
# such connection requests will not be logged.
|
|
#
|
|
# See the comment at the top of this section for a description of log levels
|
|
#
|
|
|
|
MACLIST_LOG_LEVEL=info
|
|
|
|
#
|
|
# TCP FLAGS Log Level
|
|
#
|
|
# Specifies the logging level for packets that fail TCP Flags
|
|
# verification. If set to the empty value (TCP_FLAGS_LOG_LEVEL="") then
|
|
# such packets will not be logged.
|
|
#
|
|
# See the comment at the top of this section for a description of log levels
|
|
#
|
|
|
|
TCP_FLAGS_LOG_LEVEL=info
|
|
|
|
#
|
|
# RFC1918 Log Level
|
|
#
|
|
# Specifies the logging level for packets that fail RFC 1918
|
|
# verification. If set to the empty value (RFC1918_LOG_LEVEL="") then
|
|
# RFC1918_LOG_LEVEL=info is assumed.
|
|
#
|
|
# See the comment at the top of this section for a description of log levels
|
|
#
|
|
|
|
RFC1918_LOG_LEVEL=info
|
|
|
|
################################################################################
|
|
# L O C A T I O N O F F I L E S A N D D I R E C T O R I E S
|
|
################################################################################
|
|
#
|
|
# PATH - Change this if you want to change the order in which Shorewall
|
|
# searches directories for executable files.
|
|
#
|
|
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin
|
|
|
|
#
|
|
# SHELL
|
|
#
|
|
# The firewall script is normally interpreted by /bin/sh. If you wish to change
|
|
# the shell used to interpret that script, specify the shell here.
|
|
|
|
SHOREWALL_SHELL=/bin/sh
|
|
|
|
# SUBSYSTEM LOCK FILE
|
|
#
|
|
# Set this to the name of the lock file expected by your init scripts. For
|
|
# RedHat, this should be /var/lock/subsys/shorewall. If your init scripts don't
|
|
# use lock files, set this to "".
|
|
#
|
|
|
|
SUBSYSLOCK=/var/lock/subsys/shorewall
|
|
|
|
#
|
|
# SHOREWALL TEMPORARY STATE DIRECTORY
|
|
#
|
|
# This is the directory where the firewall maintains state information while
|
|
# it is running
|
|
#
|
|
|
|
STATEDIR=/var/lib/shorewall
|
|
|
|
#
|
|
# KERNEL MODULE DIRECTORY
|
|
#
|
|
# If your netfilter kernel modules are in a directory other than
|
|
# /lib/modules/$(uname -r)/kernel/net/ipv4/netfilter then specify that
|
|
# directory in this variable. Example: MODULESDIR=/etc/modules.
|
|
|
|
MODULESDIR=
|
|
|
|
################################################################################
|
|
# F I R E W A L L O P T I O N S
|
|
################################################################################
|
|
|
|
# NAME OF THE FIREWALL ZONE
|
|
#
|
|
# Name of the firewall zone -- if not set or if set to an empty string, "fw"
|
|
# is assumed.
|
|
#
|
|
FW=fw
|
|
|
|
#
|
|
# ENABLE IP FORWARDING
|
|
#
|
|
# If you say "On" or "on" here, IPV4 Packet Forwarding is enabled. If you
|
|
# say "Off" or "off", packet forwarding will be disabled. You would only want
|
|
# to disable packet forwarding if you are installing Shorewall on a
|
|
# standalone system or if you want all traffic through the Shorewall system
|
|
# to be handled by proxies.
|
|
#
|
|
# If you set this variable to "Keep" or "keep", Shorewall will neither
|
|
# enable nor disable packet forwarding.
|
|
#
|
|
IP_FORWARDING=On
|
|
|
|
#
|
|
# AUTOMATICALLY ADD NAT IP ADDRESSES
|
|
#
|
|
# If you say "Yes" or "yes" here, Shorewall will automatically add IP addresses
|
|
# for each NAT external address that you give in /etc/shorewall/nat. If you say
|
|
# "No" or "no", you must add these aliases youself.
|
|
#
|
|
ADD_IP_ALIASES=Yes
|
|
|
|
#
|
|
# AUTOMATICALLY ADD SNAT IP ADDRESSES
|
|
#
|
|
# If you say "Yes" or "yes" here, Shorewall will automatically add IP addresses
|
|
# for each SNAT external address that you give in /etc/shorewall/masq. If you say
|
|
# "No" or "no", you must add these aliases youself. LEAVE THIS SET TO "No" unless
|
|
# you are sure that you need it -- most people don't!!!
|
|
#
|
|
ADD_SNAT_ALIASES=No
|
|
|
|
#
|
|
# ENABLE TRAFFIC SHAPING
|
|
#
|
|
# If you say "Yes" or "yes" here, Traffic Shaping is enabled in the firewall. If
|
|
# you say "No" or "no" then traffic shaping is not enabled. If you enable traffic
|
|
# shaping you must have iproute[2] installed (the "ip" and "tc" utilities) and
|
|
# you must enable packet mangling above.
|
|
#
|
|
TC_ENABLED=No
|
|
|
|
#
|
|
# Clear Traffic Shapping/Control
|
|
#
|
|
# If this option is set to 'No' then Shorewall won't clear the current
|
|
# traffic control rules during [re]start. This setting is intended
|
|
# for use by people that prefer to configure traffic shaping when
|
|
# the network interfaces come up rather than when the firewall
|
|
# is started. If that is what you want to do, set TC_ENABLED=Yes and
|
|
# CLEAR_TC=No and do not supply an /etc/shorewall/tcstart file. That
|
|
# way, your traffic shaping rules can still use the 'fwmark'
|
|
# classifier based on packet marking defined in /etc/shorewall/tcrules.
|
|
#
|
|
# If omitted, CLEAR_TC=Yes is assumed.
|
|
|
|
CLEAR_TC=Yes
|
|
|
|
#
|
|
# Mark Packets in the forward chain
|
|
#
|
|
# When processing the tcrules file, Shorewall normally marks packets in the
|
|
# PREROUTING chain. To cause Shorewall to use the FORWARD chain instead, set
|
|
# this to "Yes". If not specified or if set to the empty value (e.g.,
|
|
# MARK_IN_FORWARD_CHAIN="") then MARK_IN_FORWARD_CHAIN=No is assumed.
|
|
#
|
|
# Marking packets in the FORWARD chain has the advantage that inbound
|
|
# packets destined for Masqueraded/SNATed local hosts have had their destination
|
|
# address rewritten so they can be marked based on their destination. When
|
|
# packets are marked in the PREROUTING chain, packets destined for
|
|
# Masqueraded/SNATed local hosts still have a destination address corresponding
|
|
# to the firewall's external interface.
|
|
#
|
|
# Note: Older kernels do not support marking packets in the FORWARD chain and
|
|
# setting this variable to Yes may cause startup problems.
|
|
|
|
MARK_IN_FORWARD_CHAIN=No
|
|
|
|
#
|
|
# MSS CLAMPING
|
|
#
|
|
# Set this variable to "Yes" or "yes" if you want the TCP "Clamp MSS to PMTU"
|
|
# option. This option is most commonly required when your internet
|
|
# interface is some variant of PPP (PPTP or PPPoE). Your kernel must
|
|
# have CONFIG_IP_NF_TARGET_TCPMSS set.
|
|
#
|
|
# [From the kernel help:
|
|
#
|
|
# This option adds a `TCPMSS' target, which allows you to alter the
|
|
# MSS value of TCP SYN packets, to control the maximum size for that
|
|
# connection (usually limiting it to your outgoing interface's MTU
|
|
# minus 40).
|
|
#
|
|
# This is used to overcome criminally braindead ISPs or servers which
|
|
# block ICMP Fragmentation Needed packets. The symptoms of this
|
|
# problem are that everything works fine from your Linux
|
|
# firewall/router, but machines behind it can never exchange large
|
|
# packets:
|
|
# 1) Web browsers connect, then hang with no data received.
|
|
# 2) Small mail works fine, but large emails hang.
|
|
# 3) ssh works fine, but scp hangs after initial handshaking.
|
|
# ]
|
|
#
|
|
# If left blank, or set to "No" or "no", the option is not enabled.
|
|
#
|
|
CLAMPMSS=No
|
|
|
|
#
|
|
# ROUTE FILTERING
|
|
#
|
|
# Set this variable to "Yes" or "yes" if you want kernel route filtering on all
|
|
# interfaces started while Shorewall is started (anti-spoofing measure).
|
|
#
|
|
# If this variable is not set or is set to the empty value, "No" is assumed.
|
|
# Regardless of the setting of ROUTE_FILTER, you can still enable route filtering
|
|
# on individual interfaces using the 'routefilter' option in the
|
|
# /etc/shorewall/interfaces file.
|
|
|
|
ROUTE_FILTER=No
|
|
|
|
#
|
|
# NAT BEFORE RULES
|
|
#
|
|
# Shorewall has traditionally processed static NAT rules before port forwarding
|
|
# rules. If you would like to reverse the order, set this variable to "No".
|
|
#
|
|
# If this variable is not set or is set to the empty value, "Yes" is assumed.
|
|
|
|
NAT_BEFORE_RULES=Yes
|
|
|
|
# DNAT IP ADDRESS DETECTION
|
|
#
|
|
# Normally when Shorewall encounters the following rule:
|
|
#
|
|
# DNAT net loc:192.168.1.3 tcp 80
|
|
#
|
|
# it will forward TCP port 80 connections from the net to 192.168.1.3
|
|
# REGARDLESS OF THE ORIGINAL DESTINATION ADDRESS. This behavior is
|
|
# convenient for two reasons:
|
|
#
|
|
# a) If the the network interface has a dynamic IP address, the
|
|
# firewall configuration will work even when the address
|
|
# changes.
|
|
#
|
|
# b) It saves having to configure the IP address in the rule
|
|
# while still allowing the firewall to be started before the
|
|
# internet interface is brought up.
|
|
#
|
|
# This default behavior can also have a negative effect. If the
|
|
# internet interface has more than one IP address then the above
|
|
# rule will forward connection requests on all of these addresses;
|
|
# that may not be what is desired.
|
|
#
|
|
# By setting DETECT_DNAT_IPADDRS=Yes, rules such as the above will apply
|
|
# only if the original destination address is the primary IP address of
|
|
# one of the interfaces associated with the source zone. Note that this
|
|
# requires all interfaces to the source zone to be up when the firewall
|
|
# is [re]started.
|
|
|
|
DETECT_DNAT_IPADDRS=No
|
|
|
|
#
|
|
# MUTEX TIMEOUT
|
|
#
|
|
# The value of this variable determines the number of seconds that programs
|
|
# will wait for exclusive access to the Shorewall lock file. After the number
|
|
# of seconds corresponding to the value of this variable, programs will assume
|
|
# that the last program to hold the lock died without releasing the lock.
|
|
#
|
|
# If not set or set to the empty value, a value of 60 (60 seconds) is assumed.
|
|
#
|
|
# An appropriate value for this parameter would be twice the length of time
|
|
# that it takes your firewall system to process a "shorewall restart" command.
|
|
|
|
MUTEX_TIMEOUT=60
|
|
|
|
#
|
|
# NEWNOTSYN
|
|
#
|
|
# TCP connections are established using the familiar three-way "handshake":
|
|
#
|
|
# CLIENT SERVER
|
|
#
|
|
# SYN-------------------->
|
|
# <------------------SYN,ACK
|
|
# ACK-------------------->
|
|
#
|
|
# The first packet in that exchange (packet with the SYN flag on and the ACK
|
|
# and RST flags off) is referred to in Netfilter terminology as a "syn" packet.
|
|
# A packet is said to be NEW if it is not part of or related to an already
|
|
# established connection.
|
|
#
|
|
# The NETNOTSYN option determines the handling of non-SYN packets (those with
|
|
# SYN off or with ACK or RST on) that are not associated with an already
|
|
# established connection.
|
|
#
|
|
# If NEWNOTSYN is set to "No" or "no", then non-SYN packets that are not
|
|
# part of an already established connection, it will be dropped by the
|
|
# firewall. The setting of LOGNEWNOTSYN above determines if these packets are
|
|
# logged before they are dropped.
|
|
#
|
|
# If NEWNOTSYN is set to "Yes" or "yes" then such packets will not be
|
|
# dropped but will pass through the normal rule/policy processing.
|
|
#
|
|
# Users with a High-availability setup with two firewall's and one acting
|
|
# as a backup should set NEWNOTSYN=Yes. Users with asymmetric routing may
|
|
# also need to select NEWNOTSYN=Yes.
|
|
#
|
|
# The behavior of NEWNOTSYN=Yes may also be enabled on a per-interface basis
|
|
# using the 'newnotsyn' option in /etc/shorewall/interfaces.
|
|
#
|
|
# I find that NEWNOTSYN=No tends to result in lots of "stuck"
|
|
# connections because any network timeout during TCP session tear down
|
|
# results in retries being dropped (Netfilter has removed the
|
|
# connection from the conntrack table but the end-points haven't
|
|
# completed shutting down the connection). I therefore have chosen
|
|
# NEWNOTSYN=Yes as the default value.
|
|
|
|
NEWNOTSYN=Yes
|
|
|
|
#
|
|
# FOR ADMINS THAT REPEATEDLY SHOOT THEMSELVES IN THE FOOT
|
|
#
|
|
# Normally, when a "shorewall stop" command is issued or an error occurs during
|
|
# the execution of another shorewall command, Shorewall puts the firewall into
|
|
# a state where only traffic to/from the hosts listed in
|
|
# /etc/shorewall/routestopped is accepted.
|
|
#
|
|
# When performing remote administration on a Shorewall firewall, it is
|
|
# therefore recommended that the IP address of the computer being used for
|
|
# administration be added to the firewall's /etc/shorewall/routestopped file.
|
|
#
|
|
# Some administrators have a hard time remembering to do this with the result
|
|
# that they get to drive across town in the middle of the night to restart
|
|
# a remote firewall (or worse, they have to get someone out of bed to drive
|
|
# across town to restart a very remote firewall).
|
|
#
|
|
# For those administrators, we offer ADMINISABSENTMINDED=Yes. With this setting,
|
|
# when the firewall enters the 'stopped' state:
|
|
#
|
|
# All traffic that is part of or related to established connections is still
|
|
# allowed and all OUTPUT traffic is allowed. This is in addition to traffic
|
|
# to and from hosts listed in /etc/shorewall/routestopped.
|
|
#
|
|
# If this variable is not set or it is set to the null value then
|
|
# ADMINISABSENTMINDED=No is assumed.
|
|
#
|
|
ADMINISABSENTMINDED=Yes
|
|
|
|
#
|
|
# BLACKLIST Behavior
|
|
#
|
|
# Shorewall offers two types of blacklisting:
|
|
#
|
|
# - static blacklisting through the /etc/shorewall/blacklist file together
|
|
# with the 'blacklist' interface option.
|
|
# - dynamic blacklisting using the 'drop', 'reject' and 'allow' commands.
|
|
#
|
|
# The following variable determines whether the blacklist is checked for each
|
|
# packet or for each new connection.
|
|
#
|
|
# BLACKLISTNEWONLY=Yes Only consult blacklists for new connection
|
|
# requests
|
|
#
|
|
# BLACKLISTNEWONLY=No Consult blacklists for all packets.
|
|
#
|
|
# If the BLACKLISTNEWONLY option is not set or is set to the empty value then
|
|
# BLACKLISTNEWONLY=No is assumed.
|
|
#
|
|
BLACKLISTNEWONLY=Yes
|
|
|
|
# MODULE NAME SUFFIX
|
|
#
|
|
# When loading a module named in /etc/shorewall/modules, Shorewall normally
|
|
# looks in the MODULES DIRECTORY (see MODULESDIR above) for files whose names
|
|
# end in ".o", ".ko", ".gz" or "o.gz". If your distribution uses a different
|
|
# naming convention then you can specify the suffix (extension) for module
|
|
# names in this variable.
|
|
#
|
|
# To see what suffix is used by your distribution:
|
|
#
|
|
# ls /lib/modules/$(uname -r)/kernel/net/ipv4/netfilter
|
|
#
|
|
# All of the file names listed should have the same suffix (extension). Set
|
|
# MODULE_SUFFIX to that suffix.
|
|
#
|
|
# Examples:
|
|
#
|
|
# If all file names end with ".kzo" then set MODULE_SUFFIX="kzo"
|
|
# If all file names end with ".kz.o" then set MODULE_SUFFIX="kz.o"
|
|
#
|
|
|
|
MODULE_SUFFIX=
|
|
|
|
################################################################################
|
|
# P A C K E T D I S P O S I T I O N
|
|
################################################################################
|
|
#
|
|
# BLACKLIST DISPOSITION
|
|
#
|
|
# Set this variable to the action that you want to perform on packets from
|
|
# Blacklisted systems. Must be DROP or REJECT. If not set or set to empty,
|
|
# DROP is assumed.
|
|
#
|
|
BLACKLIST_DISPOSITION=DROP
|
|
|
|
#
|
|
# MAC List Disposition
|
|
#
|
|
# This variable determines the disposition of connection requests arriving
|
|
# on interfaces that have the 'maclist' option and that are from a device
|
|
# that is not listed for that interface in /etc/shorewall/maclist. Valid
|
|
# values are ACCEPT, DROP and REJECT. If not specified or specified as
|
|
# empty (MACLIST_DISPOSITION="") then REJECT is assumed
|
|
|
|
MACLIST_DISPOSITION=REJECT
|
|
|
|
#
|
|
# TCP FLAGS Disposition
|
|
#
|
|
# This variable determins the disposition of packets having an invalid
|
|
# combination of TCP flags that are received on interfaces having the
|
|
# 'tcpflags' option specified in /etc/shorewall/interfaces. If not specified
|
|
# or specified as empty (TCP_FLAGS_DISPOSITION="") then DROP is assumed.
|
|
|
|
TCP_FLAGS_DISPOSITION=DROP
|
|
|
|
#LAST LINE -- DO NOT REMOVE
|