BS Daemon
2021-05-18 19:08:48 UTC
I am hoping that I'm just doing something wrong, but it appears
that while relayd supports some Server Name Identification (SNI)
functionality, it does not support SNI for it's man-in-the-middle
/ TLS inspection configuration. Years ago I used relayd to permit access
only to certain browsers
by User_Agent string and was hoping to do the same now. But with
SNI not working, and the amount of use of SNI in the world today,
this is no longer workerable. I peaked at the code, but don't have the
expertise to to make the
feature work. I like using the base OpenBSD utilities, and was
wondering if I'm doing something wrong, if relayd could be made to
support SNI for man-in-the-middle, or if there is an alternative
tool for doing this which would work. As an example:
At the time of writing, BSDCan, a BSD conference in Canada, has a
web site with two names: www.bsdcan.org and www.bsdcan.ca. They
both are hosted at a single IP and Port. Each site uses it's own
server certificate. The default site as far as TLS is concerned is
www.bsdcan.ca, so unless one provides the SNI host name, one gets
the certificate for this server name. Interestingly, www.bsdcan.ca
redirects the clients to www.bsdcan.org. When a client goes to
www.bsdcan.org, but does not provide the SNI server name, one gets
the certificate for www.bsdcan.ca. The result is that if the client
does not have SNI abilities enabled, the browsers throws a warning
message.
Without relayd in the path:
# This will get certificate for bsdcan.ca:
libressl s_client -connect www.bsdcan.ca:443
# This will also get certificate for bsdcan.ca (no SNI in request):
libressl s_client -connect www.bsdcan.org:443
# This will get certificate for bsdcan.org
libressl s_client -servername www.bsdcan.org -connect www.bsdcan.org:443
# This will also get certificate for bsdcan.org (SNI requests this site)
libressl s_client -servername www.bsdcan.org -connect www.bsdcan.ca:443With
relayd in the path, as configured below,
# This will get certificate for bsdcan.ca
# (SNI requested, but relayd is not handling SNI for TLS inspection)
libressl s_client -servername www.bsdcan.org -connect www.bsdcan.org:443
relayd.conf:------------------------------------------------------------------------
log connection
http protocol httpfilter {
# Return HTTP/HTML error pages to the client
return error
match header log "User-Agent"
match url log
# Block disallowed sites
match request label "URL filtered!"
block request quick url "www.example.com/" value "*"
# Pass allowed browsers
match request label "User-Agent Good"
pass request quick header "User-Agent" \
value "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:*.0) Gecko/20100101
Firefox/*"
pass request quick header "User-Agent" \
value "Microsoft-CryptoAPI/10.0"
# Block all other browsers
match request label "Please try a <em>different Browser</em>"
block request quick header "User-Agent" \
value "*"
tls ca key "/etc/ssl/relayd/private/ca.key" password "PASSWORD"
tls ca cert "/etc/ssl/relayd/ca.crt"
}
relay httpproxy {
listen on 127.0.0.1 port 8080
protocol httpfilter
forward to destination
}
relay tlsinspect {
listen on 127.0.0.1 port 8443 tls
protocol httpfilter
forward with tls to destination
}
------------------------------------------------------------------------
that while relayd supports some Server Name Identification (SNI)
functionality, it does not support SNI for it's man-in-the-middle
/ TLS inspection configuration. Years ago I used relayd to permit access
only to certain browsers
by User_Agent string and was hoping to do the same now. But with
SNI not working, and the amount of use of SNI in the world today,
this is no longer workerable. I peaked at the code, but don't have the
expertise to to make the
feature work. I like using the base OpenBSD utilities, and was
wondering if I'm doing something wrong, if relayd could be made to
support SNI for man-in-the-middle, or if there is an alternative
tool for doing this which would work. As an example:
At the time of writing, BSDCan, a BSD conference in Canada, has a
web site with two names: www.bsdcan.org and www.bsdcan.ca. They
both are hosted at a single IP and Port. Each site uses it's own
server certificate. The default site as far as TLS is concerned is
www.bsdcan.ca, so unless one provides the SNI host name, one gets
the certificate for this server name. Interestingly, www.bsdcan.ca
redirects the clients to www.bsdcan.org. When a client goes to
www.bsdcan.org, but does not provide the SNI server name, one gets
the certificate for www.bsdcan.ca. The result is that if the client
does not have SNI abilities enabled, the browsers throws a warning
message.
Without relayd in the path:
# This will get certificate for bsdcan.ca:
libressl s_client -connect www.bsdcan.ca:443
# This will also get certificate for bsdcan.ca (no SNI in request):
libressl s_client -connect www.bsdcan.org:443
# This will get certificate for bsdcan.org
libressl s_client -servername www.bsdcan.org -connect www.bsdcan.org:443
# This will also get certificate for bsdcan.org (SNI requests this site)
libressl s_client -servername www.bsdcan.org -connect www.bsdcan.ca:443With
relayd in the path, as configured below,
# This will get certificate for bsdcan.ca
# (SNI requested, but relayd is not handling SNI for TLS inspection)
libressl s_client -servername www.bsdcan.org -connect www.bsdcan.org:443
relayd.conf:------------------------------------------------------------------------
log connection
http protocol httpfilter {
# Return HTTP/HTML error pages to the client
return error
match header log "User-Agent"
match url log
# Block disallowed sites
match request label "URL filtered!"
block request quick url "www.example.com/" value "*"
# Pass allowed browsers
match request label "User-Agent Good"
pass request quick header "User-Agent" \
value "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:*.0) Gecko/20100101
Firefox/*"
pass request quick header "User-Agent" \
value "Microsoft-CryptoAPI/10.0"
# Block all other browsers
match request label "Please try a <em>different Browser</em>"
block request quick header "User-Agent" \
value "*"
tls ca key "/etc/ssl/relayd/private/ca.key" password "PASSWORD"
tls ca cert "/etc/ssl/relayd/ca.crt"
}
relay httpproxy {
listen on 127.0.0.1 port 8080
protocol httpfilter
forward to destination
}
relay tlsinspect {
listen on 127.0.0.1 port 8443 tls
protocol httpfilter
forward with tls to destination
}
------------------------------------------------------------------------