Files
op-packages/luci-app-squid-adv/files/luci.squid-adv
T

196 lines
7.9 KiB
Bash
Executable File

#!/bin/sh
. /usr/share/libubox/jshn.sh
. /lib/functions.sh
CERTS=/etc/squid/cert
FILE=/tmp/luci.squid-adv.tmp
CONF=$(uci get squid.@squid[0].config_file)
trap 'rm ${FILE} 2> /dev/null' EXIT
##########################################################################################################
# Function to check firewall to see if proxy firewall rule is setup correctly:
##########################################################################################################
check_firewall() {
src_port=$1
dst_port=$2
dst_ip=${dst_port%:*}
dst_port=${dst_port#*:}
[[ "${dst_port}" == "${dst_ip}" ]] && dst_ip=${ip_addr}
[[ "$src_port" -eq 80 ]] && proto=HTTP || proto=HTTPS
# Does the firewall settings need to be changed? If not, abort:
uci -q show firewall.tproxy_${src_port} > ${FILE}
CUR_ZONE=$(grep ".src=" ${FILE} | cut -d= -f 2 | sed "s|'||g")
CUR_PORT=$(grep ".dest_port=" ${FILE} | cut -d= -f 2 | sed "s|'||g")
CUR_SRC=$(grep ".src_dip=" ${FILE} | cut -d= -f 2 | sed "s|'||g" | sed "s|\!||g")
CUR_DST=$(grep ".dest_ip=" ${FILE} | cut -d= -f 2 | sed "s|'||g")
[[ "${CUR_ZONE}" == "${zone}" && "${CUR_PORT}" == "${http_port}" && "${CUR_SRC}" == "${ip_addr}" && "${CUR_DST}" == "${ip_addr}" ]] && return
# Setup transparent proxy firewall rules for specified outgoing port:
uci -q delete firewall.tproxy_${src_port}
uci set firewall.tproxy_${src_port}='redirect'
uci set firewall.tproxy_${src_port}.name="$(echo ${interface} | tr 'a-z' 'A-Z') ${proto} to Squid"
uci set firewall.tproxy_${src_port}.src="${interface}"
uci set firewall.tproxy_${src_port}.proto="tcp"
uci set firewall.tproxy_${src_port}.src_dport="${src_port}"
uci set firewall.tproxy_${src_port}.dest_port="${dst_port}"
uci set firewall.tproxy_${src_port}.src_dip='!'${dst_ip}
uci set firewall.tproxy_${src_port}.dest_ip="${dst_ip}"
uci set firewall.tproxy_${src_port}.target="dnat"
}
##########################################################################################################
# Main code
##########################################################################################################
case "$1" in
list)
json_init
json_add_object "cert_info"
json_close_object
json_add_object "reconfigure"
json_close_object
json_add_object "generate"
json_add_string 'bits' 'Integer'
json_add_string 'days' 'Integer'
json_add_string 'countryName' 'String'
json_add_int 'stateOrProvinceName' 'String'
json_add_string 'localityName' 'String'
json_add_int 'organizationName' 'String'
json_close_object
json_add_object "ip_info"
json_close_object
json_add_object "parse_config"
json_close_object
json_dump
;;
############################################################################################
config)
case "$2" in
####################################################################################
read)
cat ${CONF}
;;
####################################################################################
move)
mv /tmp/luci-app-squid-adv.data ${CONF}
;;
esac
;;
############################################################################################
call)
case "$2" in
####################################################################################
parse_config)
# Determine which interface zone current configuration is using:
echo -n "{"
IFACE=$(uci -q show firewall.tproxy_80.src | cut -d= -f 2 | sed "s|'||g")
[[ -z "${IFACE}" ]] && IFACE=$(uci -q show firewall.tproxy_443.src | cut -d= -f 2 | sed "s|'||g")
echo -n "\"interface\":\"${IFACE}\","
# Determine if transparent HTTP proxy is in use:
echo -n "\"http_port\":\"$(grep "^http_port .* intercept$" ${SRC} | awk '{print $2}')\","
# Determine if transparent HTTPS proxy is in use:
echo "\"https_port\":\"$(grep "^http_port .* intercept .*ssl-bump" ${SRC} | awk '{print $2}')\"}"
;;
####################################################################################
reconfigure)
# Get the settings we need for this action:
config_load squid
config_get interface transparent interface
config_get http_enabled transparent http_enabled
config_get http_port transparent http_port
config_get https_enabled transparent https_enabled
config_get https_port transparent https_port
# Specify defaults if not specified, then get IP address of specified interface:
interface=${interface:-"lan"}
http_port=${http_port:-"3126"}
https_port=${https_port:-"3127"}
ip_addr=$(uci get network.${interface}.ipaddr)
# Update HTTP intercept lines in "squid.conf":
if [[ "${http_enabled}" != "1" ]]; then
uci -q delete firewall.tproxy_80
sed -i "/^http_port .* intercept$/d" ${CONF}
else
check_firewall 80 ${http_port}
sed -i "/^http_port .* intercept$/d" ${CONF}
echo "http_port ${http_port} intercept" >> ${CONF}
fi
# Update HTTPS intercept lines in "squid.conf":
if [[ "${https_enabled}" != "1" ]]; then
uci -q delete firewall.tproxy_443
sed -i "/^http_port .* intercept.*ssl-bump/d" ${CONF}
else
check_firewall 443 ${https_port}
sed -i "/^http_port .* intercept.*ssl-bump/d" ${CONF}
echo "http_port ${https_port} intercept tcpkeepalive=60,30,3 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=${CERTS}/ca.pem key=${CERTS}/ca.key cipher=HIGH:MEDIUM:!LOW:!RC4:!SEED:!IDEA:!3DES:!MD5:!EXP:!PSK:!DSS options=NO_TLSv1,NO_SSLv3 tls-dh=prime256v1:${CERTS}/dhparam.pem" >> ${CONF}
fi
# Restart services as required:
uci commit firewall
/sbin/service firewall restart
;;
####################################################################################
generate)
read input
json_load "$input"
json_get_var bits "bits"
json_get_var days "days"
json_get_var country "country"
json_get_var state "state"
json_get_var locality "locality"
json_get_var organization "organization"
# Generate OpenSSL certificates, using defaults if option is not set:
mkdir -p ${CERTS}
rm ${CERTS}/ca.* 2> /dev/null
openssl req -new -x509 -newkey rsa:${bits} -days ${days} -nodes -keyout ${CERTS}/ca.key -out ${CERTS}/ca.pem -subj "/C=${country}/ST=${state}/L=${locality}/O=${organization}" 2>&1
openssl x509 -in ${CERTS}/ca.pem -outform DER -out ${CERTS}/ca.der 2>&1
openssl pkcs12 -export -out ${CERTS}/ca.p12 -in ${CERTS}/ca.pem -inkey ${CERTS}/ca.key -passout pass: -nokeys 2>&1
chmod 0644 ${CERTS}/ca.*
chmod 0600 ${CERTS}/ca.key
# Generate needed symlinks to make the web portion work properly:
DST=/www/ca
mkdir -p ${DST}
ln -sf ${CERTS}/ca.der ${DST}/squid-ca.cer
ln -sf ${CERTS}/ca.pem ${DST}/squid-ca.pem
ln -sf ${CERTS}/ca.p12 ${DST}/squid-ca.p12
;;
####################################################################################
cert_info)
VALID=false
test -f ${CERTS}/ca.pem && openssl x509 -noout -subject -in ${CERTS}/ca.pem -nameopt multiline -checkdates -dates -dateopt iso_8601 > ${FILE} && VALID=true
echo -n "{"
if [[ "${VALID}" == "true" ]]; then
cat ${FILE} | while read LINE; do
VAR=$(echo "${LINE%%=*}" | xargs)
VAL="$(echo "${LINE#*=}" | xargs)"
[[ "${#VAL}" -gt 0 ]] && echo -n "\"${VAR}\":\"${VAL}\","
if [[ "${VAR}" == "notBefore" || "${VAR}" == "notAfter" ]]; then
VAL=$(echo "${VAL}" | sed "s/[[:alpha:]]//g")
[[ "${VAR}" == "notBefore" ]] && DAYS=$(date -d"${VAL}" +%s)
[[ "${VAR}" == "notAfter" ]] && echo -n "\"days\":\"$(( ($(date -d"${VAL}" +%s) - ${DAYS}) / (60*60*24) ))\","
fi
done
echo -n "\"bits\":\"$(openssl x509 -noout -in ${CERTS}/ca.pem -text | grep "Public-Key" | grep -o "[0-9]*")\","
fi
echo "\"valid\":${VALID}}"
;;
####################################################################################
ip_info)
curl ipinfo.io 2> /dev/null || echo "{}"
;;
esac
;;
esac