# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:sw=4:ts=4:sts=4
PortSystem 1.0
name adblock2privoxy
version 2.3.0
revision 0
categories www haskell
maintainers {ieee.org:s.t.smith @essandess} openmaintainer
license GPL-3
description Convert adblock config files to privoxy format
long_description {*}${description}. \
AdBlock Plus browser plugin has great block list \
files provided by big community, but it is client \
software and cannot work on a server as proxy. \
Privoxy proxy has good potential to block ads at \
server side, but it experiences acute shortage of \
updated block lists. This software converts \
adblock lists to privoxy config files format. \
Almost all adblock features are supported \
including block/unblock requests (on privoxy) all \
syntax features are supported except for regex \
templates matching host name hide/unhide page \
elements (via CSS) all syntax features are \
supported all block request options except for \
outdated ones: Supported: script, image, \
stylesheet, object, xmlhttprequest, \
object-subrequest, subdocument, document, \
elemhide, other, popup, third-party, domain=..., \
match-case, donottrack.
homepage https://github.com/essandess/adblock2privoxy
checksums rmd160 2c672d9742a76fd01f0715e2b0ac45c4a6f4a9bd \
sha256 bd6a0b2f7a922a314608392ff2aad299f28337c5c97d6723b03c7abdfb4c5f29 \
size 44257
depends_lib-append port:zlib
depends_run-append port:bash \
port:nginx \
port:privoxy \
port:wget
depends_skip_archcheck \
privoxy
variant initialize_always \
description {Always initialize all configuration files. Intended\
for development and troubleshooting only. Working deployments\
must disable this variant to prevent configuration files\
being overwritten at the next upgrade. Existing configuration\
files are not overwritten by default.} {
pre-fetch {
ui_warn \
"All configuration files will be initialized because\
the variant +initialize_always is set. Please disable\
this variant for working deployments."
}
}
# use domain or ip with port, e.g. 127.0.0.1:8119
set adblock2privoxy_css_server \
127.0.0.1:8119
# relative paths to ${prefix}
set ab2p_datadir share/${name}
post-extract {
# Fix for cabal data-files hardcoded path in binary
# See:
# https://github.com/commercialhaskell/stack/issues/848
# https://github.com/commercialhaskell/stack/issues/4857
# https://github.com/haskell/cabal/issues/462
# https://github.com/haskell/cabal/issues/3586
xinstall -m 0644 -W ${worksrcpath} \
${filespath}/Paths_NAME.hs ./src/Paths_${name}.hs
reinplace "s|@PREFIX@|${prefix}|g" \
${worksrcpath}/src/Paths_${name}.hs
reinplace "s|@NAME@|${name}|g" \
${worksrcpath}/src/Paths_${name}.hs
reinplace -E "s|(Version\[\[:space:\]\]+)\\\[\[\[:digit:\]\]+(,\[\[:digit:\]\]+){1,4}\\\]|\\1\[[join [split ${version} .] ,]\]|" \
${worksrcpath}/src/Paths_${name}.hs
}
variant stack \
description {Use stack to build.} {}
if { [variant_isset "stack"] } {
PortGroup haskell_stack 1.0
post-destroot {
xinstall -d ${destroot}${prefix}/share/${name}/templates
# cabal's data-files datadir: ${name}_datadir from Paths_${name}.hs
fs-traverse f ${worksrcpath}/.stack-work {
if { [string match "ab2p.system.*" [file tail ${f}]] } {
xinstall -m 0644 ${f} \
${destroot}${prefix}/share/${name}/templates
}
}
}
} else {
PortGroup haskell_cabal 1.0
build.target-append \
--allow-newer
post-destroot {
xinstall -d ${destroot}${prefix}/share/${name}/templates
foreach f [glob ${worksrcpath}/templates/ab2p.system.*] {
xinstall -m 0644 ${f} \
${destroot}${prefix}/share/${name}/templates
}
}
}
post-destroot {
xinstall -m 0644 -W ${worksrcpath} \
man/man1/${name}.1 \
${destroot}${prefix}/share/man/man1
xinstall -d \
${destroot}${prefix}/etc/${name} \
${destroot}${prefix}/etc/${name}/bin \
${destroot}${prefix}/etc/${name}/css \
${destroot}${prefix}/etc/${name}/privoxy
xinstall -m 0755 -W ${filespath} \
adblock2privoxy_initialize.sh \
${destroot}${prefix}/etc/${name}/bin
reinplace "s|@PREFIX@|${prefix}|g" \
${destroot}${prefix}/etc/${name}/bin/adblock2privoxy_initialize.sh
xinstall -m 0644 -W ${filespath} \
adblock2privoxy_blocklist.txt \
${destroot}${prefix}/etc/${name}/adblock2privoxy_blocklist.txt.macports
xinstall -m 0644 -W ${filespath} \
nginx.conf \
${destroot}${prefix}/etc/${name}/nginx.conf.macports
xinstall -m 0644 -W ${filespath} \
default.html \
${destroot}${prefix}/etc/${name}/css/default.html.macports
reinplace "s|@PREFIX@|${prefix}|g" \
${destroot}${prefix}/etc/${name}/nginx.conf.macports
}
set tls_ca_dir ${prefix}/etc/${name}/ca.macports
set tls_cert_dir ${prefix}/etc/${name}/certs
set optional_proxy http://localhost:8080
set proxy_message \
"Startupitem configured to use a proxy. Please set the
environment variables http_proxy and https_proxy and
install this port variant a sudo command that sets
these variables, e.g.:
\tsudo -E port install ${name} +proxy_settings
\tsudo env http_proxy=${optional_proxy} port install ${name} +proxy_settings
or edit the startupitem:
\t${prefix}/etc/${startupitem.location}/org.macports.${name}/org.macports.${name}.plist
to change the proxy settings and reload the port."
variant proxy_settings \
description {Include proxy settings in the startupitem plist.} {
# Note: `sudo launchctl setenv` is no longer functional on macOS Ventura+
notes-append ${proxy_message}
post-activate {
if { [info exists ::env(http_proxy)] } {
set http_proxy $env(http_proxy)
} else {
set http_proxy ${optional_proxy}
}
if { [info exists ::env(https_proxy)] } {
set https_proxy $env(https_proxy)
} else {
set https_proxy ${http_proxy}
}
# org.macports.adblock2privoxy
reinplace \
"s|^ProgramArguments|EnvironmentVariables\\
\\
http_proxy\\
${http_proxy}\\
https_proxy\\
${https_proxy}\\
\\
&|" \
${prefix}/etc/${startupitem.location}/org.macports.${name}/org.macports.${name}.plist
ui_msg "${proxy_message}
The startupitem is configured to use the proxy settings:
\thttp_proxy=${http_proxy}
\thttps_proxy=${https_proxy}
"
}
}
variant https_inspection \
description {HTTPS CSS Server for use with 'privoxy +https_inspection'.} {
depends_build-append \
port:sf-pwgen
depends_lib-append \
path:bin/openssl:openssl
# random 4-word-based passphrase
proc correct_horse_battery_staple {} {
# ignore errors from sf-pwgen if the password is shorter than requested
set passphrase \
[join [exec sh -c "sf-pwgen \
--algorithm memorable --count 2 --length 16 \
2>/dev/null || true"] -]
# set random passphrase if sf-pwgen's is too short for some reason
if {[string length ${passphrase}] < 20} {
set passphrase \
[exec sh -c "openssl rand -base64 23 2>/dev/null \
| sed 's|=*\$||' || true"]
}
return ${passphrase}
}
post-destroot {
# TLS Root CA configuration
xinstall -m 0770 -d ${destroot}${tls_cert_dir}
xinstall -m 0700 -d ${destroot}${tls_ca_dir}
destroot.keepdirs-append \
${destroot}${tls_cert_dir}
xinstall -m 0644 -W ${filespath} \
openssl.cnf \
${destroot}${tls_ca_dir}/openssl.cnf.macports
}
pre-activate {
if { [file exists ${tls_ca_dir}] } {
delete ${tls_ca_dir}.previous
move ${tls_ca_dir} \
${tls_ca_dir}.previous
}
}
post-activate {
foreach f [list \
${tls_ca_dir}/openssl.cnf \
] {
if { [variant_isset "initialize_always"]
&& [file exists ${f}]
} {
delete ${f}.previous
move \
${f} \
${f}.previous
}
if { [variant_isset "initialize_always"]
|| ![file exists ${f}]
} {
if { [file isfile ${f}.macports] } {
xinstall -m 0644 \
${f}.macports \
${f}
}
}
}
# CA passphrase
# generate a strong password, use for openssl -passin and -passout
set tls_ca_passphrase \
[correct_horse_battery_staple]
set tls_ca_passphrase_fd \
[open ${tls_ca_dir}/passphrase.txt w 0600]
# -passin or -passout
puts ${tls_ca_passphrase_fd} \
${tls_ca_passphrase}
# -passout
puts ${tls_ca_passphrase_fd} \
${tls_ca_passphrase}
close ${tls_ca_passphrase_fd}
# create the root CA
system -W ${tls_ca_dir} \
"sh < serial
# CA encrypted key
# EC
openssl genpkey -out ca.key.pem -algorithm EC \\
-pkeyopt ec_paramgen_curve:P-384 -aes256 \\
-pass file:passphrase.txt
# RSA
# openssl genpkey -out ca.key.pem -algorithm RSA \\
# -pkeyopt rsa_keygen_bits:2048 -aes256 \\
# -passout file:passphrase.txt
chmod go-rw ca.key.pem
# CA certificate
openssl req -config openssl.cnf \\
-new -x509 -days 1460 -sha384 \\
-extensions v3_ca \\
-out ca.cert.pem -key ca.key.pem \\
-passin file:passphrase.txt -batch
# CA certificate openssl self-verification
openssl verify -CAfile ca.cert.pem ca.cert.pem
# Convert to .cer DER and .p12 for other uses
openssl x509 -outform der -in ca.cert.pem -out ca.cer
# https://github.com/essandess/macports-ports/pull/new/privoxy
openssl pkcs12 -legacy -export -out ca.p12 \\
-inkey ca.key.pem -in ca.cert.pem \\
-passin file:passphrase.txt \\
-passout file:passphrase.txt
# verify .p12 passphrase
openssl pkcs12 -legacy -noout -in ca.p12 -passin file:passphrase.txt
# Server certificates
# Server certificate encrypted key and decrypted key
openssl genpkey -out adblock2privoxy-nginx.key.pem \
-algorithm EC -pkeyopt ec_paramgen_curve:P-384 -aes256 \
-pass file:passphrase.txt
openssl ec -in adblock2privoxy-nginx.key.pem \
-passin file:passphrase.txt \
-out adblock2privoxy-nginx.key.pem.decrypted
chmod go-rwx adblock2privoxy-nginx.key.pem.decrypted
# Server certificate CSR
openssl req -config openssl.cnf -new -sha384 \
-key adblock2privoxy-nginx.key.pem \
-passin file:passphrase.txt \
-out adblock2privoxy-nginx.csr.pem -batch
# Server certificate (825 days maximum validity)
# https://support.apple.com/en-us/HT210176
openssl ca -config openssl.cnf -days 825 -notext -md sha384 \
-extensions server_cert -in adblock2privoxy-nginx.csr.pem \
-out adblock2privoxy-nginx.cert.pem \
-passin file:passphrase.txt \
-subj '/CN=adblock2privoxy-nginx' -batch
# Server certificate chain of trust
cat adblock2privoxy-nginx.cert.pem ca.cert.pem \
> adblock2privoxy-nginx.chain.pem
# Server certificate and chain validity
openssl verify -CAfile ca.cert.pem adblock2privoxy-nginx.cert.pem
openssl verify -CAfile ca.cert.pem adblock2privoxy-nginx.chain.pem
ADBLOCK2PRIVOXY_PKI
"
if { ![file exists ${tls_cert_dir}/adblock2privoxy-nginx.cert.pem]
|| ![file exists ${tls_cert_dir}/adblock2privoxy-nginx.key.pem.decrypted]
} {
xinstall -m 0664 \
${tls_ca_dir}/ca.cert.pem \
${tls_cert_dir}
xinstall -m 0664 \
${tls_ca_dir}/ca.key.pem \
${tls_cert_dir}
xinstall -m 0600 \
${tls_ca_dir}/passphrase.txt \
${tls_cert_dir}
xinstall -m 0664 \
${tls_ca_dir}/adblock2privoxy-nginx.cert.pem \
${tls_cert_dir}
xinstall -m 0664 \
${tls_ca_dir}/adblock2privoxy-nginx.chain.pem \
${tls_cert_dir}
xinstall -m 0664 \
${tls_ca_dir}/adblock2privoxy-nginx.key.pem \
${tls_cert_dir}
xinstall -m 0600 \
${tls_ca_dir}/adblock2privoxy-nginx.key.pem.decrypted \
${tls_cert_dir}
}
if { ![file exists ${tls_cert_dir}/dhparam.pem]
} {
system -W ${tls_ca_dir} \
"sh </dev/null 2>&1; \
then echo 'WONT_EXPIRE'; \
else echo 'WILL_EXPIRE'; fi"]
if {[string trim ${ab2p_cert_valid}] ne {WONT_EXPIRE}} {
ui_warn "Certificate ${tls_cert_dir}/adblock2privoxy-nginx.cert.pem expired or will expire within 30 days."
}
}
notes-append \
"Configure adblock2privoxy PKI by creating a\
certificate from e.g. Privoxy's certificate authority (CA). As sudo:
# Example, more likely use ${prefix}/etc/privoxy/CA
cp -R ${prefix}/etc/privoxy/ca.macports ca.adblock2privoxy \\
&& cd ca.adblock2privoxy
cp ${tls_cert_dir}/openssl.cnf .
# edit openssl.cnf for your local organizationName, commonName, etc.
# initialize
touch index.txt
echo 1000 > serial
# Server certificates
# Server certificate encrypted key and decrypted key
openssl genpkey -out adblock2privoxy-nginx.key.pem \\
-algorithm EC -pkeyopt ec_paramgen_curve:P-384 -aes256 \\
-pass file:passphrase.txt
openssl ec -in adblock2privoxy-nginx.key.pem \\
-passin file:passphrase.txt \\
-out adblock2privoxy-nginx.key.pem.decrypted
chmod go-rwx adblock2privoxy-nginx.key.pem.decrypted
# Server certificate CSR
openssl req -config openssl.cnf -new -sha384 \\
-key adblock2privoxy-nginx.key.pem \\
-passin file:passphrase.txt \\
-out adblock2privoxy-nginx.csr.pem -batch
# Server certificate (825 days maximum validity)
# https://support.apple.com/en-us/HT210176
openssl ca -config openssl.cnf -days 825 -notext -md sha384 \\
-extensions server_cert -in adblock2privoxy-nginx.csr.pem \\
-out adblock2privoxy-nginx.cert.pem \\
-passin file:passphrase.txt \\
-subj '/CN=adblock2privoxy-nginx' -batch
# Server certificate chain of trust
cat adblock2privoxy-nginx.cert.pem ca.cert.pem \\
> adblock2privoxy-nginx.chain.pem
# Server certificate and chain validity
openssl verify -CAfile ca.cert.pem adblock2privoxy-nginx.cert.pem
openssl verify -CAfile ca.cert.pem adblock2privoxy-nginx.chain.pem
# Install the adblock2privoxy PKI
cp -p ca.key.pem ca.cert.pem passphrase.txt \\
adblock2privoxy-nginx.cert.pem adblock2privoxy-nginx.chain.pem \\
adblock2privoxy-nginx.key.pem \\
adblock2privoxy-nginx.key.pem.decrypted \\
${tls_cert_dir}
"
}
default_variants-append \
+https_inspection
# default: empty flag
set ab2p_use_http_flag \
{}
if { ![variant_isset "https_inspection"] } {
set ab2p_use_http_flag \
{-u}
}
startupitem.create yes
startupitems \
name ${name} \
init [list "if \[ -f \"\${prefix}/etc/adblock2privoxy/ADBLOCK2PRIVOXY.env\" ]; then" \
"\tset -a" \
"\t. <(grep -E -o -e '^\[\[:alnum:]_]+=\[^\[:space:]\;]+\$' \"${prefix}/etc/adblock2privoxy/ADBLOCK2PRIVOXY.env\" | grep -E -v '^\[\[:space:]]*(#|\$)|\\\$\\(|`')" \
"\tset +a" \
"fi" \
"ADBLOCK2PRIVOXY_CSS_SERVER=\"\${ADBLOCK2PRIVOXY_CSS_SERVER:-${adblock2privoxy_css_server}}\"" \
] \
start [list "( IFS=\$'\\n' ADBLOCK2PRIVOXY_BLOCKLIST=(\$(grep -v -e '^ *#' < \"\${prefix}/etc/${name}/adblock2privoxy_blocklist.txt\" \\" \
"\t| while read -r t; do if \"\${prefix}/bin/wget\" --max-redirect=0 -S --spider \"\${t}\" 2>&1 | grep -q 'HTTP/1.1 200 OK'; then echo \"\${t}\"; fi done)); \\" \
"/bin/test -f \"\${prefix}/etc/adblock2privoxy/privoxy/ab2p.task\" \\" \
"&& \"\${prefix}/bin/adblock2privoxy\" -t \"\${prefix}/etc/adblock2privoxy/privoxy/ab2p.task\" \\" \
"|| \"\${prefix}/bin/adblock2privoxy\" -p \"\${prefix}/etc/adblock2privoxy/privoxy\" \\" \
"\t-w \"\${prefix}/etc/adblock2privoxy/css\" \\" \
"\t-d \"\${ADBLOCK2PRIVOXY_CSS_SERVER}\" ${ab2p_use_http_flag} \\" \
"\t\"\${ADBLOCK2PRIVOXY_BLOCKLIST\[@]}\" \\" \
") && \"\${prefix}/bin/port\" reload privoxy" \
] \
stop "\"/usr/bin/kill -SIGUSR1 \\\"\$(/usr/bin/pgrep -u root ${name})\\\" 2>/dev/null\"" \
pidfile none
startupitems-append \
name ${name}-nginx \
init "pidfile=\"\${prefix}/var/run/nginx/nginx-adblock2privoxy.pid\"" \
start [list "\"\${prefix}/sbin/nginx\" \\" \
"\t-c \\" \
"\t\"\${prefix}/etc/${name}/nginx.conf\" \\" \
"\t-g \"daemon off;\"" \
] \
stop [list "if \[ -f \"\${pidfile}\" \]; then" \
"\t/usr/bin/kill \"\$(cat \"\${pidfile}\")\" \\" \
"\t\t&& /bin/rm -f \"\${pidfile}\" ;" \
"else" \
"\t/usr/bin/kill -SIGUSR1 \"\$(/usr/bin/pgrep -u root nginx)\" 2>/dev/null ;" \
"fi" \
]
post-destroot {
# org.macports.adblock2privoxy
reinplace -E \
"1s|^(#!\[\[:space:]]*)/bin/sh|\\1/usr/bin/env bash|" \
${destroot}${prefix}/etc/${startupitem.location}/org.macports.${name}/${name}.wrapper
reinplace \
"s|^ProgramArguments|StartCalendarInterval\\
\\
\\
Weekday\\
7\\
Hour\\
1\\
Minute\\
30\\
\\
\\
StandardErrorPath\\
${prefix}/var/log/${name}.log\\
StandardOutPath\\
${prefix}/var/log/${name}.log\\
&|" \
${destroot}${prefix}/etc/${startupitem.location}/org.macports.${name}/org.macports.${name}.plist
}
post-activate {
foreach f [list \
${prefix}/etc/${name}/adblock2privoxy_blocklist.txt \
${prefix}/etc/${name}/nginx.conf \
${prefix}/etc/${name}/css/default.html \
] {
if { [variant_isset "initialize_always"]
&& [file exists ${f}]
} {
delete ${f}.previous
move \
${f} \
${f}.previous
}
if { [variant_isset "initialize_always"]
|| ![file exists ${f}]
} {
if { [file isfile ${f}.macports] } {
xinstall -m 0644 \
${f}.macports \
${f}
}
}
}
}
notes "\
After initial installation, it is necessary to kickstart this launch daemon,\
which does not run at load:
sudo launchctl kickstart -k system/org.macports.adblock2privoxy
The blocklist URLs are specified in the file\
${prefix}/etc/${name}/adblock2privoxy_blocklist.txt.
Example production run:
adblock2privoxy -p ${prefix}/etc/adblock2privoxy/privoxy \\
-w ${prefix}/etc/adblock2privoxy/css -d ${adblock2privoxy_css_server} \\
\$(< ${prefix}/etc/${name}/adblock2privoxy_blocklist.txt)
Update run:
adblock2privoxy -t ${prefix}/etc/adblock2privoxy/privoxy/ab2p.task
The CSS web server domain name or IP address is specified by the\
environment variable ADBLOCK2PRIVOXY_CSS_SERVER (with default value):
ADBLOCK2PRIVOXY_CSS_SERVER=${adblock2privoxy_css_server}
To change this or site-specific environment variables, set them in the\
optional file
${prefix}/etc/adblock2privoxy/ADBLOCK2PRIVOXY.env
Please note that the macOS command `launchctl setenv` is now prohibited by SIP.
"
if { [variant_isset "initialize_always"] } {
if {[exists notes]} {
# leave a blank line after the existing notes
notes-append ""
}
notes-append \
"The variant +initialize_always is set, which initializes\
all configuration files. Please disable this variant for\
working deployments."
}