RELAYD.CONF(5) | File Formats Manual | RELAYD.CONF(5) |
relayd.conf
—
relay daemon configuration file
relayd.conf
is the configuration file for
the relay daemon,
relayd(8).
relayd.conf
is divided into seven main
sections:
Within the sections, a host address can be specified by IPv4 address, IPv6 address, interface name, interface group, or DNS hostname. If the address is an interface name, relayd(8) will look up the first IPv4 address and any other IPv4 and IPv6 addresses of the specified network interface. A port can be specified by number or name. The port name to number mappings are found in the file /etc/services; see services(5) for details.
The current line can be extended over multiple lines using a backslash (‘\’). Comments can be put anywhere in the file using a hash mark (‘#’), and extend to the end of the current line. Care should be taken when commenting out multi-line text: the comment is effective until the end of the entire block.
Argument names not beginning with a letter, digit, or underscore must be quoted.
Additional configuration files can be included with the
include
keyword, for example:
include "/etc/relayd.conf.local"
Macros can be defined that will later be expanded in context.
Macro names must start with a letter, digit, or underscore, and may contain
any of those characters. Macro names may not be reserved words (for example,
table
, relay
, or
timeout
). Macros are not expanded inside quotes.
For example:
www1="10.0.0.1" www2="10.0.0.2" table <webhosts> { $www1 $www2 }
Here are the settings that can be set globally:
interval
numberlog
(updates
|all
)updates
to new states or log
all
state notifications, even if the state didn't
change. The host state can be “up” (the health check
completed successfully), “down” (the host is down or didn't
match the check criteria), or “unknown” (the host is
disabled or has not been checked yet).prefork
numbersnmp
[trap
] ["path"]timeout
numberTables are used to group a set of hosts as the target for redirections or relays; they will be mapped to a pf(4) table for redirections. Tables may be defined with the following attribute:
disable
Each table must contain at least one host address; multiple hosts are separated by newline, comma, or whitespace. Host entries may be defined with the following attributes:
ip ttl
numberparent
numbershow summary
commands.priority
numberRTP_STATIC
). In
ordinary use, a fallback route should be added statically with a very high
(e.g. 52) priority. Unused in all other modes.retry
numberFor example:
table <service> { 192.168.1.1, 192.168.1.2, 192.168.2.3 } table <fallback> disable { 10.1.5.1 retry 2 } redirect "www" { listen on www.example.com port 80 forward to <service> check http "/" code 200 forward to <fallback> check http "/" code 200 }
Tables are used by forward to
directives
in redirections or relays with a set of general options, health-checking
rules, and timings; see the
REDIRECTIONS and
RELAYS sections for more information about
the forward context. Table specific configuration directives are described
below. Multiple options can be appended to forward
to
directives, separated by whitespaces.
The following options will configure the health-checking method for the table, and is mandatory for redirections:
check
http
path [host
hostname] code
number$ echo -n "HEAD <path> HTTP/1.0\r\n\r\n" | \ nc <host> <port> | head -n1
This prints the status header including the actual return code:
HTTP/1.1 200 OK
check
https
path [host
hostname] code
numbercheck
http
path [host
hostname] digest
stringrelayd.conf
expects the data returned to be a string. To compute the digest, use this
simple command:
$ ftp -o - http://host[:port]/path | sha1
This gives a digest that can be used as-is in a digest statement:
a9993e36476816aba3e25717850c26c9cd0d89d
check
https
path [host
hostname] digest
stringcheck
icmp
check
script
path/usr/local/bin/checkload.pl front-www1.private.example.com
relayd(8) expects a positive return value on success and zero on failure. Note that the script will be executed with the privileges of the "_relayd" user and terminated after timeout milliseconds.
check
send
data expect
pattern [tls
]nothing
then nothing is sent on the connection and
data is immediately read. This can be useful with protocols that output a
banner like SMTP, NNTP, and FTP. If the tls
keyword is present, the transaction will occur in a TLS tunnel.check
tcp
check
tls
The following general table options are available:
demote
groupgroup
keyword in
ifconfig(8).interval
numbertimeout
numberThe following options will set the scheduling algorithm to select a host from the specified table:
mode
hash
[key]mode
least-states
mode
loadbalance
[key]mode
random
mode
roundrobin
mode
source-hash
[key]The optional key argument can be specified
for the hash
, loadbalance
,
and source-hash
modes as either a hex value with a
leading ‘0x
’ or as a string. If
omitted, relayd(8) generates
a random key when the configuration is loaded.
Redirections represent a
pf(4) rdr-to rule. They are used
for stateful redirections to the hosts in the specified tables.
pf(4) rewrites the target IP
addresses and ports of the incoming connections, operating on layer 3. The
configuration directives that are valid in the
redirect
context are described below:
disable
forward
to
<table>
[port
number]
options ...port
option is not
specified, the first port from the listen on
directive will be used. This directive can be specified twice – the
second entry will be used as the backup table if all hosts in the main
table are down. At least one entry for the main table is mandatory.listen
on
address [ip-proto]
port
port
[interface
name]tcp
or
udp
; it defaults to tcp
.
The rule can be optionally restricted to a given interface name.route to
<table>
[port
number]
options ...forward to
directive, but directly routes
the packets to the target host without modifying the target address using
a pf(4) route-to rule. This can
be used for “direct server return” to force the target host
to respond via a different gateway. Note that hosts have to accept
sessions for the same address as the gateway, which is typically done by
configuring a loopback interface on the host with this address.session
timeout
secondssticky-address
match
] pftag
namematch
keyword will change the default rule action
from ‘pass in quick
’ to
‘match in
’ to allow further
evaluation in the pf ruleset using the tagged
name rule option.Relays will forward traffic between a client and a target server. In contrast to redirections and IP forwarding in the network stack, a relay will accept incoming connections from remote clients as a server, open an outgoing connection to a target host, and forward any traffic between the target host and the remote client, operating on layer 7. A relay is also called an application layer gateway or layer 7 proxy.
The main purpose of a relay is to provide advanced load balancing functionality based on specified protocol characteristics, such as HTTP headers, to provide TLS acceleration and to allow basic handling of the underlying application protocol.
The relay
configuration directives are
described below:
disable
transparent
] forward
[with tls
] to
address [port
port] options ...port
option is not specified, the port from the
listen on
directive will be used. Use the
transparent
keyword to enable fully-transparent
mode; the source address of the client will be retained in this case.
The with tls
directive enables
client-side TLS mode to connect to the remote host. Verification of
server certificates can be enabled by setting the ca
file
option in the protocol section.
The following options may be specified for forward directives:
retry
numberretry
option will be used as
a tolerance for failed host connections; the connection will be
retried for number more times.inet
inet6
address-prefixforward
to
<table>
[port
port]
options ...with tls
directive to enable client-side TLS mode when connecting to the remote
host.forward
to
destination
options
...forward to
directive to a specified address or table is present, it will be used as a
backup if the lookup failed. As above, use the with
tls
directive to enable client-side TLS mode when connecting to the
remote host.forward
to
nat lookup
options
...listen
on
address port
port [tls
]If the tls
keyword is present, the
relay will accept connections using the encrypted TLS protocol. The
relay will attempt to look up a private key in
/etc/ssl/private/address:port.key and a public
certificate in /etc/ssl/address:port.crt, where
address is the specified IP address and
port is the specified port that the relay listens
on. If these files are not present, the relay will continue to look in
/etc/ssl/private/address.key and
/etc/ssl/address.crt. See
ssl(8) for details about
SSL/TLS server certificates.
protocol
namesession
timeout
secondsIn addition to plain TCP, relayd(8) supports the Transport Layer Security (TLS) cryptographic protocol for authenticated and encrypted relays. TLS is the successor of the original Secure Sockets Layer (SSL) protocol, but the term SSL is sometimes still used in modern TLS-based applications. relayd(8) can operate as a TLS client or server to offer a variety of options for different use cases related to TLS.
TLS
client
forward
statements with
the with tls
directive,
relayd(8) will enable
client-side TLS to connect to the remote host. This is commonly used for
TLS tunneling and transparent encapsulation of plain TCP connections. See
the forward to
description in the
RELAYS section for more details.TLS
server
tls
keyword in the relay
listen
statements,
relayd(8) will accept
connections from clients as a TLS server. This mode is also known as
“SSL/TLS acceleration”. See the listen
on
description in the RELAYS
section for more details.TLS client
and server
ca key
description in the PROTOCOLS section
for more details.When configured for “TLS inspection” mode, relayd(8) will listen for incoming connections which have been diverted to the local socket by PF. Before accepting and negotiating the incoming TLS connection as a server, it will look up the original destination address on the diverted socket, and pre-connect to the target server as a TLS client to obtain the remote TLS certificate. It will update or patch the obtained TLS certificate by replacing the included public key with its local server key because it doesn't have the private key of the remote server certificate. It also updates the X.509 issuer name to the local CA subject name and signs the certificate with its local CA key. This way it keeps all the other X.509 attributes that are already present in the server certificate, including the "green bar" extended validation attributes. Now it finally accepts the TLS connection from the diverted client using the updated certificate and continues to handle the connection and to connect to the remote server.
Protocols are templates defining settings and rules for relays. They allow setting generic TCP options, TLS settings, and rules for the selected application layer protocol.
The protocol directive is available for a number of different application layer protocols. There is no generic handler for UDP-based protocols because it is a stateless datagram-based protocol which has to look into the application layer protocol to find any possible state information.
dns
protocol
http
protocol
tcp
] protocol
The available configuration directives are described below:
block
|pass
|match
)
[rule]return
error
[option]style
stringbody { background: #a00000; color: white; }
tcp
optionbacklog
numberkern.somaxconn
sysctl(8)
variable.ip
minttl
numberip
ttl
numberno
] nodelay
no
] sack
socket
buffer
numberno
] splice
tls
optionca
cert
pathca key
option below.ca
file
pathca
key
path
password
passwordlisten
directive: listen on ... tls
.forward
directive:
forward with tls to destination
.ca cert
option is specified.ca key
option is specified.ciphers
stringHIGH:!aNULL
’ will
be used (strong crypto cipher suites without anonymous DH). See the
CIPHERS section of
openssl(1) for
information about SSL/TLS cipher suites and preference lists.no
]
cipher-server-preference
no
]
client-renegotiation
ecdh
[curve
name]prime256v1
will be used. ECDHE is enabled by
default.no ecdh
edh
[params
maximum]no edh
session
cache
valuedisable
will disable
the TLS session cache.no
] sslv3
no
] tlsv1
tlsv1.0
, tlsv1.1
, and
tlsv1.2
.no
] tlsv1.0
no
] tlsv1.1
no
] tlsv1.2
Relays have the ability to filter connections based on their network or application layer headers. Filter rules apply options to connections based on the specified filter parameters.
For each connection that is processed by a relay, the filter rules
are evaluated in sequential order, from first to last. For
block
and pass
, the last
matching rule decides what action is taken; if no rule matches the
connection, the default action is to establish the connection without any
additional action. For match
, rules are evaluated
every time they match; the pass/block state of a connection remains
unchanged.
The filter action may be one of the following:
block
block
rule matches
a new connection attempt, it will not be established.
block
rules can also trigger for existing
connections after evaluating application layer parameters; any connection
of the relay session will be instantly dropped.match
pass
These filter parameters can be used in the rules:
request
or response
request
, a client initiating a new connection to a
server via the relay, and the response
, the server
accepting the connection. Depending on the protocol, an established
session can be purely request/response-based (like HTTP), exchange data in
a bidirectional way (like arbitrary TCP sessions), or just contain a
single datagram and an optional response (like UDP-based protocols). But
the client always
requests
to communicate with a remote peer; the server.quick
quick
option set, the rule is considered to be the
last matching rule and any further evaluation is skipped.inet
or inet6
label
stringreturn error
option is set and may contain HTML
tags, for example:
block request url digest 5c1e03f58f8ce0b457474ffb371fd1ef \ label "<a href='http://example.com/adv.pl?id=7359'>\ Advisory provided by example.com</a>"
no
parameterlabel
or tag
.tag
stringtagged
option. Only one tag is assigned per
connection; the tag will be replaced if the connection is already
tagged.tagged
stringforward
to
<table>forward to
declaration in the
RELAYS section is required.The following parameters are available when using the
http
protocol:
method
nameCONNECT
, COPY
,
DELETE
, GET
,
HEAD
, LOCK
,
MKCOL
, MOVE
,
OPTIONS
, PATCH
,
POST
, PROPFIND
,
PROPPATCH
, PUT
,
TRACE
, or UNLOCK
.digest
]
(key|file
path) [value
value]]key
and value
. An
option
can be specified to modify the matched
entity or to trigger an event. The entity is extracted from the HTTP
request or response header and can be either of type
cookie
, header
,
path
, query
, or
url
.
Instead of a single key, multiple keys
can be loaded from a file
specified by
path that contains one key per line. Lines will be
stripped at the first whitespace or newline character and any empty
lines or lines beginning with a hash mark
(‘#
’) will be ignored.
If the digest
keyword is specified,
compare the message digest of the key against the defined string. The
algorithm used is determined by the string length of the
key argument, either SHA1 (40 characters) or MD5
(32 characters). To compute the digest, for example for a
url
, use this simple command:
$ echo -n "example.com/path/?args" | sha1
[type] may be one of:
request
.header
option [key
[value
value]]http
mode.path
option [key
[value
value]]http
protocol. This type is only available with
the direction request
. The
key will match the path of the requested URL without
the hostname and query and the value will match the complete query, for
example:
block path "/index.html" block path "/cgi-bin/t.cgi" value "foo=bar*"
query
option [key
[value
value]]http
protocol. This type is only available with
the direction request
, for example:
# Will match /cgi-bin/example.pl?foo=bar&ok=yes request query expect "bar" from "foo"
url
option [[digest
]
key [value
value]]http
protocol. This type is only
available with the direction request
, for example:
block url "example.com/index.html" block url "example.com/test.cgi?val=1"
relayd(8) will match the full URL and different possible suffix/prefix combinations by stripping subdomains and path components (up to 5 levels), and the query string. For example, the following lookups will be done for http://www.example.com:81/1/2/3/4/5.html?query=yes:
www.example.com/1/2/3/4/5.html?query=yes www.example.com/1/2/3/4/5.html www.example.com/ www.example.com/1/ www.example.com/1/2/ www.example.com/1/2/3/ example.com/1/2/3/4/5.html?query=yes example.com/1/2/3/4/5.html example.com/ example.com/1/ example.com/1/2/ example.com/1/2/3/
[option] may be one of:
append
The value string may contain predefined macros that will be expanded at runtime:
$REMOTE_ADDR
$REMOTE_PORT
$SERVER_ADDR
$SERVER_PORT
$SERVER_NAME
$TIMEOUT
hash
table
keyword in the
RELAYS section above.log
remove
set
append
directive above, but change the
contents of the specified entity. If key does not
exist in the request, it will be created with the new
value.
The value string may contain predefined
macros that will be expanded at runtime, as detailed for the
append
directive above.
Routers represent routing table entries in the kernel forwarding database, see route(4), and a table of associated gateways. They are used to dynamically insert or remove routes with gateways based on their availability and health-check results. A router can include multiple network statements and a single forward statement with a table of one or more gateways. All entries in a single router directive must match the same address family, either IPv4 or IPv6.
The kernel supports multipath routing when multiple gateways exist to the same destination address. The multipath routing behaviour can be changed globally using the sysctl(8) variables net.inet.ip.multipath and net.inet6.ip6.multipath. With the default setting of 0, the first route selected will be used for subsequent packets to that destination regardless of source. Setting it to 1 will enable load balancing based on the packet source address across gateways; multiple routes with the same priority are used equally. The kernel will also check the link state of the related network interface and try a different route if it is not active.
The configuration directives that are valid in the
routers
context are described below:
forward
to
<table>
port
number
options ...route
address/
prefixrtable
idrtlabel
labelThis configuration file would create a redirection service “www” which load balances four hosts and falls back to one host containing a “sorry page”:
www1=front-www1.private.example.com www2=front-www2.private.example.com www3=front-www3.private.example.com www4=front-www4.private.example.com interval 5 table <phphosts> { $www1, $www2, $www3, $www4 } table <sorryhost> disable { sorryhost.private.example.com } redirect "www" { listen on www.example.com port 8080 interface trunk0 listen on www6.example.com port 80 interface trunk0 pftag REDIRECTED forward to <phphosts> port 8080 timeout 300 \ check http "/" digest "630aa3c2f..." forward to <sorryhost> port 8080 timeout 300 check icmp }
It is possible to specify multiple listen directives with different IP protocols in a single redirection configuration:
redirect "dns" { listen on dns.example.com tcp port 53 listen on dns.example.com udp port 53 forward to <dnshosts> port 53 check tcp }
The following configuration would add a relay to forward secure
HTTPS connections to a pool of HTTP webservers using the
loadbalance
mode (TLS acceleration and layer 7 load
balancing). The HTTP protocol definition will add two HTTP headers
containing address information of the client and the server, set the
“Keep-Alive” header value to the configured session timeout,
and include the “sessid” variable in the hash to calculate the
target host:
http protocol "https" { match header append "X-Forwarded-For" \ value "$REMOTE_ADDR" match header append "X-Forwarded-By" \ value "$REMOTE_ADDR:$SERVER_PORT" match header set "Keep-Alive" value "$TIMEOUT" match query hash "sessid" match hash "sessid" pass block path "/cgi-bin/index.cgi" value "*command=*" tls { no tlsv1.0, ciphers "HIGH" } } relay "tlsaccel" { listen on www.example.com port 443 tls protocol "https" forward to <phphosts> port 8080 mode loadbalance check tcp }
The second relay example will accept incoming connections to port
2222 and forward them to a remote SSH server. The TCP
nodelay
option will allow a “smooth”
SSH session without delays between keystrokes or displayed output on the
terminal:
protocol "myssh" { tcp { nodelay, socket buffer 65536 } } relay "sshforward" { listen on www.example.com port 2222 protocol "myssh" forward to shell.example.com port 22 }
The following relay example will configure “TLS inspection” as described in the TLS RELAYS section. To start, first generate a new local CA key and certificate:
# openssl req -x509 -days 365 -newkey rsa:2048 \ -keyout /etc/ssl/private/ca.key -out /etc/ssl/ca.crt
A TLS server key and self-signed cert for 127.0.0.1 are also
required; see listen on
in the
RELAYS section for more details about
certificate locations. Configure the packet filter with a matching divert
rule in pf.conf(5):
# Divert incoming HTTPS traffic to relayd pass in on vlan1 inet proto tcp to port 443 \ divert-to localhost port 8443
And finally configure the TLS inspection in
relayd.conf
:
http protocol httpfilter { return error pass match label "Prohibited!" block url "social.network.example.com/" # New configuration directives for SSL/TLS Interception tls ca key "/etc/ssl/private/ca.key" password "password123" tls ca cert "/etc/ssl/ca.crt" } relay tlsinspect { listen on 127.0.0.1 port 8443 tls protocol httpfilter forward with tls to destination }
The next simple router configuration example can be used to run redundant, health-checked WAN links:
table <gateways> { $gw1 ip ttl 1, $gw2 ip ttl 1 } router "uplinks" { route 0.0.0.0/0 forward to <gateways> check icmp }
The relayd.conf
file format, formerly
known as hoststated.conf
, first appeared in
OpenBSD 4.1. It was renamed to
relayd.conf
in OpenBSD
4.3.
The relayd(8) program was written by Pierre-Yves Ritschard <pyr@openbsd.org> and Reyk Floeter <reyk@openbsd.org>.
relayd(8) Verification of TLS server certificates is based on a static CA bundle and relayd(8) currently does not support CRLs (Certificate Revocation Lists).
November 6, 2015 | OpenBSD-5.9 |