Skip to content

Instantly share code, notes, and snippets.

@gretel
Last active December 4, 2022 07:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gretel/2ea31f98fa4471e53e7a8fc97f9c16d3 to your computer and use it in GitHub Desktop.
Save gretel/2ea31f98fa4471e53e7a8fc97f9c16d3 to your computer and use it in GitHub Desktop.
"openbinge" put relayd and varnishd in front of some (ob)httpd serving mp4 files to get a html-less video streaming endpoint (pf -> relayd -> varnish -> obhttpd -> file)
# $OpenBSD: httpd.conf,v 1.20 2018/06/13 15:08:24 reyk Exp $
chroot "/zfs/videos"
logdir "/var/log"
server "*" {
listen on 10.0.100.20 port 8442
tcp nodelay
tcp sack
tcp socket buffer 65536
tcp backlog 100
no log
root "/"
location "/*" {
directory auto index
}
}
$piq on $lan_if inet proto tcp from any to (self) \
port $stream_ports_tcp \
keep state (max 200, source-track rule, max-src-nodes 50, max-src-states 100, max-src-conn-rate 100/60) \
rdr-to 127.0.0.1 \
label "$if<$proto:$dstport"
$piq on $lan_if inet6 proto tcp from any to (self) \
port $stream_ports_tcp \
keep state (max 200, source-track rule, max-src-nodes 50, max-src-states 100, max-src-conn-rate 100/60) \
rdr-to ::1 \
label "$if<$proto:$dstport"
varnishd_flags=-s malloc,256M -p http_gzip_support=off -p fetch_chunksize=56k -p send_timeout=30 -p feature=+http2 -h critbit -n streaming -f /etc/varnish/streaming.vcl -a 127.0.0.1:
8442 -P /var/run/varnishd.pid -j unix,user=_varnish
http protocol "streaming" {
# match request header set "Connection" value "keep-alive"
# your web application might need these headers
match request header set "X-Forwarded-For" value "$REMOTE_ADDR"
match request header set "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT"
# set best practice security headers
# use https://securityheaders.com to check
# and modify as needed
match response header remove "Server"
match response header set "Strict-Transport-Security" value "max-age=31536000; includeSubDomains"
match response header set "X-Frame-Options" value "SAMEORIGIN"
match response header set "X-XSS-Protection" value "1; mode=block"
# match response header set "X-Content-Type-Options" value "nosniff"
match response header set "Referrer-Policy" value "strict-origin"
match response header set "Content-Security-Policy" value "default-src 'self'"
match response header set "Feature-Policy" value "accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; payment 'none';usb 'none'"
# set recommended tcp options
tcp { nodelay, sack, socket buffer 65536, backlog 100 }
}
relay "streaming4" {
listen on 127.0.0.1 port 8443 tls
protocol streaming
forward to 127.0.0.1 port 8442
}
relay "streaming6" {
listen on ::1 port 8443 tls
protocol streaming
forward to ::1 port 8442
}
# This is a basic VCL configuration file for varnish. See the vcl(7)
# man page for details on VCL syntax and semantics.
#
# Default backend definition. Set this to point to your content
# server.
#
vcl 4.0;
backend default {
.host = "10.0.100.20";
.port = "8442";
}
sub vcl_recv {
if (! req.http.Authorization ~ "Basic cm9vdDpwYXNzd29yZA==")
{
return(synth(401, "Restricted"));
}
unset req.http.Authorization;
if (req.url ~ "\.(cur|gif|jpg|jpeg|css|js|pdf|ico|png)(\?.*|)$") {
unset req.http.cookie;
unset req.http.Accept-Encoding;
unset req.http.Vary;
}
if (req.http.Range ~ "bytes=") {
set req .http.x-range = req.http.Range;
}
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
if (req.method != "GET" && req.method != "HEAD") {
/* We only deal with GET and HEAD by default */
return (pass);
}
return (hash);
}
sub vcl_hash {
if (req.http.x-range ~ "bytes=") {
hash_data(req.http.x-range);
unset req.http.Range;
}
}
sub vcl_miss {
if (req.url ~ "\.(mp4)(?=\?|&|$)" && req.http.Range ~ "bytes\=0\-$") {
unset req.http.Range;
}
}
sub vcl_deliver {
if (resp.http.CR) {
set resp.http.Content-Range = resp.http.CR;
unset resp.http.CR;
}
}
sub vcl_backend_fetch {
if (bereq.http.x-range) {
set bereq.http.Range = bereq.http.x-range;
}
}
sub vcl_synth {
if (resp.status == 401) {
set resp.status = 401;
set resp.http.Content-Type = "text/html; charset=utf-8";
set resp.http.WWW-Authenticate = "Basic realm=Authentication";
synthetic ({"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<HTML>
<HEAD>
<TITLE>Error</TITLE>
<META HTTP-EQUIV='Content-Type' CONTENT='text/html;'>
</HEAD>
<BODY><H1>401 Unauthorized.</H1></BODY>
</HTML>
"});
return(deliver);
}
}
sub vcl_backend_response {
# Varnish 4 fully supports Streaming, so use streaming here to avoid locking.
if (bereq.url ~ "^[^?]*\.(7z|avi|bz2|flac|flv|gz|mka|mkv|mov|mp3|mp4|mpeg|mpg|ogg|ogm|opus|rar|tar|tgz|tbz|txz|wav|webm|xz|zip)(\?.*)?$") {
unset beresp.http.set-cookie;
set beresp.do_stream = true; # Check memory usage it'll grow in fetch_chunksize blocks (128k by default) if the backend doesn't send a Content-Length header, so only enableit for big objects
}
if (bereq.http.x-range ~ "bytes=" && beresp.status == 206) {
set beresp.ttl = 10m;
set beresp.http.CR = beresp.http.content-range;
}
return (deliver);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment