Skip to content

Instantly share code, notes, and snippets.

@anon987654321
Created November 16, 2020 15:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anon987654321/3de6941bc557790adaa5d2e65d6c63e3 to your computer and use it in GitHub Desktop.
Save anon987654321/3de6941bc557790adaa5d2e65d6c63e3 to your computer and use it in GitHub Desktop.

relayd.conf

# OpenBSD/amd64 myserver.com

localhost="lo0"
public="vio0"

table <acme_challenge_table> { $localhost }
acme_challenge_port="5000"

table <https_redirect_table> { $localhost }
https_redirect_port="6000"

table <static_sites_table> { $localhost }
static_sites_port="7000"

table <myrailsapp1_table> { $localhost }
myrailsapp1_port="8000"

table <myrailsapp2_table> { $localhost }
myrailsapp2_port="8001"

table <myrailsapp3_table> { $localhost }
myrailsapp3_port="8002"

table <myrailsapp4_table> { $localhost }
myrailsapp4_port="8003"

http protocol "http" {
  # HTTP-01 challenge for Let's Encrypt
  # https://letsencrypt.org/docs/challenge-types/
  pass request quick path "/.well-known/acme-challenge/*" forward to <acme_challenge_table>

  pass request header "Host" value "mystaticsite.com" forward to <static_sites_table>
  pass request header "Host" value "myrailsapp1.com" forward to <myrailsapp1_table>
  pass request header "Host" value "myrailsapp2.com" forward to <myrailsapp2_table>
  pass request header "Host" value "myrailsapp3.com" forward to <myrailsapp3_table>
  pass request header "Host" value "myrailsapp4.com" forward to <myrailsapp4_table>
}

http protocol "https_reverse_proxy" {
  # Block all by default
  block

  tls { no tlsv1.0, ciphers "HIGH" }

  pass request header "Host" value "myrailsapp1.com" forward to <myrailsapp1_table>
  pass request header "Host" value "www.myrailsapp1.com" forward to <myrailsapp1_table>
  tls keypair "myrailsapp1"

  pass request header "Host" value "myrailsapp2.com" forward to <myrailsapp2_table>
  pass request header "Host" value "www.myrailsapp2.com" forward to <myrailsapp2_table>
  tls keypair "myrailsapp2"

  pass request header "Host" value "myrailsapp3.com" forward to <myrailsapp3_table>
  pass request header "Host" value "www.myrailsapp3.com" forward to <myrailsapp3_table>
  tls keypair "myrailsapp3"

  pass request header "Host" value "myrailsapp4.com" forward to <myrailsapp4_table>
  pass request header "Host" value "www.myrailsapp4.com" forward to <myrailsapp4_table>
  tls keypair "myrailsapp4"

  # httpd(8)
  pass request header "Host" value "mystaticsite.com" forward to <static_sites_table>
  pass request header "Host" value "www.mystaticsite.com" forward to <static_sites_table>

  # Address headers
  match header set "X-Client-IP" value "$REMOTE_ADDR:$REMOTE_PORT"
  match header set "X-Forwarded-For" value "$REMOTE_ADDR"
  match header set "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT"

  # Security headers
  # https://securityheaders.com/
  match response header remove "Server"
  match response header set "X-Frame-Options" value "SAMEORIGIN"
  match response header set "X-XSS-Protection" value "1; mode=block"
  match response header set "Referrer-Policy" value "strict-origin"
  match response header set "Feature-Policy" value "accelerometer 'none'; ambient-light-sensor 'none'; battery 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none'; usb 'none';"

  # Content Security Policy headers
  # https://content-security-policy.com/
  #
  # match response header set "Content-Security-Policy" value "default-src 'self';"
  #
  # Mapbox
  # https://docs.mapbox.com/mapbox-gl-js/api/#csp-directives
  # match request header "Host" value "myrailsapp3.com" tag "myrailsapp3"
  # match response tagged "myrailsapp3" header set "Content-Security-Policy" value "default-src 'self'; img-src data: blob:; worker-src blob:; child-src blob:; connect-src https://*.tiles.mapbox.com https://api.mapbox.com https://events.mapbox.com;"
  # pass quick tagged "myrailsapp3" forward to <myrailsapp3_table>
  #
  # match request header "Host" value "example.com" tag "example"
  # match response tagged "example" header set "Content-Security-Policy" value "default-src 'self'; ...;"
  # pass quick tagged "example" forward to <example_table>
}

relay "http" {
  listen on $public port http

  protocol "http"

  # Let's Encrypt
  forward to <acme_challenge_table> port $acme_challenge_port

  # Force TLS
  forward to <https_redirect_table> port $https_redirect_port

  forward to <static_sites_table> port $static_sites_port

  forward to <myrailsapp1_table> port $myrailsapp1_port
  forward to <myrailsapp2_table> port $myrailsapp2_port
  forward to <myrailsapp3_table> port $myrailsapp3_port
  forward to <myrailsapp4_table> port $myrailsapp4_port
}

relay "https" {
  listen on $public port https tls

  protocol "https_reverse_proxy"

  forward with tls to <static_sites_table> port $static_sites_port

  # Assumes Rails HTTPS redirection is enabled
  # https://api.rubyonrails.org/classes/ActionDispatch/SSL.html
  forward to <myrailsapp1_table> port $myrailsapp1_port
  forward to <myrailsapp2_table> port $myrailsapp2_port
  forward to <myrailsapp3_table> port $myrailsapp3_port
  forward to <myrailsapp4_table> port $myrailsapp4_port
}

httpd.conf

# OpenBSD/amd64 myserver.com

types {
  include "/usr/share/misc/mime.types"
}

localhost="lo0"

acme_challenge_port="5000"
https_redirect_port="6000"
static_sites_port="7000"

# HTTP

server "*" {
  listen on $localhost port $acme_challenge_port
  location "/.well-known/acme-challenge/*" {
    root "/acme"
    request strip 2
  }
}

server "mystaticsite.com" {
  listen on $localhost port $https_redirect_port
  block return 301 "https://mystaticsite.com$DOCUMENT_URI"
}

# HTTPS

server "mystaticsite.com" {
  listen on * tls port $static_sites_port
  root "/htdocs/mystaticsite"
  tls {
    certificate "/etc/ssl/mystaticsite.crt"
    key "/etc/ssl/private/mystaticsite.key"
  }
  hsts {
    preload
  }
}

server "www.mystaticsite.com" {
  listen on * tls port $static_sites_port
  tls {
    certificate "/etc/ssl/mystaticsite.crt"
    key "/etc/ssl/private/mystaticsite.key"
  }
  block return 301 "https://mystaticsite.com$DOCUMENT_URI"
}

pf.conf

# OpenBSD/amd64 myserver.com

ext_if = "vio0"

# Allow all on localhost
set skip on lo

# Block stateless traffic
block return

# Establish keep-state
pass

# Block all incoming by default
block in

# Ban brute-force attackers
# http://home.nuug.no/~peter/pf/en/bruteforce.html
#
# pfctl -t bruteforce -T show
# pfctl -t bruteforce -T flush
# pfctl -t bruteforce -T delete <IP>
#
table <bruteforce> persist
block quick from <bruteforce>

# SSH
pass in on $ext_if inet proto tcp from any to $ext_if port 22 keep state (max-src-conn 15, max-src-conn-rate 5/3, overload <bruteforce> flush global)

# NSD
pass in on $ext_if inet proto { tcp, udp } from any to $ext_if port 53 keep state (max-src-conn 100, max-src-conn-rate 15/5, overload <bruteforce> flush global)

# httpd/relayd
pass in on $ext_if inet proto tcp from any to $ext_if port { 80, 443 } keep state

acme-client.conf

# OpenBSD/amd64 mystaticsite.com

authority letsencrypt {
  api url "https://acme-v02.api.letsencrypt.org/directory"
  account key "/etc/ssl/private/letsencrypt.key"
}

domain mystaticsite.com {
  alternative names { www.mystaticsite.com }
  domain key "/etc/ssl/private/mystaticsite.key"
  domain full chain certificate "/etc/ssl/mystaticsite.crt"
  sign with letsencrypt
}

domain myrailsapp1.com {
  alternative names { www.myrailsapp1.com }
  domain key "/etc/ssl/private/myrailsapp1.key"
  domain full chain certificate "/etc/ssl/myrailsapp1.crt"
  sign with letsencrypt
}

domain myrailsapp2.com {
  alternative names { www.myrailsapp2.com }
  domain key "/etc/ssl/private/myrailsapp2.key"
  domain full chain certificate "/etc/ssl/myrailsapp2.crt"
  sign with letsencrypt
}

domain myrailsapp3.com {
  alternative names { www.myrailsapp3.com }
  domain key "/etc/ssl/private/myrailsapp3.key"
  domain full chain certificate "/etc/ssl/myrailsapp3.crt"
  sign with letsencrypt
}

domain myrailsapp4.com {
  alternative names { www.myrailsapp4.com }
  domain key "/etc/ssl/private/myrailsapp4.key"
  domain full chain certificate "/etc/ssl/myrailsapp4.crt"
  sign with letsencrypt
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment