Skip to content

Instantly share code, notes, and snippets.

@caseyfw
Last active March 5, 2021 08:29
Show Gist options
  • Save caseyfw/5ec3af0190b8b9f0c49dcf2e8b1645a5 to your computer and use it in GitHub Desktop.
Save caseyfw/5ec3af0190b8b9f0c49dcf2e8b1645a5 to your computer and use it in GitHub Desktop.
Scripts to emulate the functionality of Proxifier in Linux by adding iptables rules to route redirect traffic via a transparent proxy.
#!/bin/bash
PORTS="22 80 443"
DEFAULT_DNS=$(nmcli device show $DEFAULT_INTERFACE | grep IP4\.DNS | awk '{print $2}' | head -n 1)
DEBUG=1
function debug {
if [ $DEBUG -eq 1 ]; then
echo $1
fi
}
# Remove output and prerouting iptables rules.
debug "Removing rules from OUTPUT and PREROUTING."
for port in $PORTS; do
iptables -t nat -D OUTPUT -p tcp -m tcp --dport $port -j proxy 2>/dev/null
iptables -t nat -D PREROUTING -p tcp -s 172.16.0.0/12 --dport $port -j proxy-docker 2>/dev/null
done
iptables -t nat -D PREROUTING -p udp -d 8.8.8.8 --dport 53 -j DNAT --to-destination $DEFAULT_DNS
# Flush the proxy and proxy-docker nat chains.
debug "Flushing proxy and proxy-docker chains."
iptables -t nat -F proxy 2>/dev/null
iptables -t nat -F proxy-docker 2>/dev/null
# Delete the proxy and proxy-docker nat chains.
debug "Deleting chains."
iptables -t nat -X proxy 2>/dev/null
iptables -t nat -X proxy-docker 2>/dev/null
# Stop any_proxy.
killall any_proxy 2>/dev/null
# Remove flight centre specific config from time sync config.
debug "Removing ntp host to timesyncd.conf."
sed -i.old '/flitech/d' /etc/systemd/timesyncd.conf
#!/bin/bash
# This script sets up a transparent proxy that intercepts all outbound traffic
# and routes it via cntlm, which adds to auth magic to make the corporate proxy
# "just work".
#
# Requires any_proxy built and available in root PATH (e.g. /usr/local/bin)
#
# You can find any_proxy here: https://github.com/ryanchapman/go-any-proxy/blob/master/any_proxy.go
# If you have docker installed, you can build by running:
# $ docker run --rm -v $PWD:$PWD -w $PWD -e "HTTP_PROXY=http://172.17.0.1:3128" -e "HTTPS_PROXY=http://172.17.0.1:3128" golang:latest bash -c "go get github.com/zdannar/flogger && ./make.bash"
# Configuration.
REMOTE_PROXY="bne-app-proxy.au.fcl.internal:3128"
ANY_PROXY_PORT=3129
PORTS="22 80 443"
LOCAL_SUBNETS="10.0.0.0/8 127.0.0.0/8 172.16.0.0/12 192.168.0.0/16 169.254.0.0/16"
DEFAULT_INTERFACE=$(ip route show default | head -n 1 | awk '/default/ {print $5}')
DEFAULT_INTERFACE_IP=$(ip -o -4 addr list $DEFAULT_INTERFACE | awk '{print $4}' | cut -d/ -f1)
DEFAULT_DNS=$(nmcli device show $DEFAULT_INTERFACE | grep IP4\.DNS | awk '{print $2}' | head -n 1)
DEBUG=1
function debug {
if [ $DEBUG -eq 1 ]; then
echo $1
fi
}
function iptables_add_if_not_present {
check=$(echo "$@" | sed 's/-A/-C/')
if ! $(iptables $check >/dev/null 2>&1); then
debug "Adding rule to iptables: $*"
$(iptables "$@")
fi
}
debug "Using interface: $DEFAULT_INTERFACE"
debug "Using IP: $DEFAULT_INTERFACE_IP"
debug "Using DNS: $DEFAULT_INTERFACE_IP"
# Start any_proxy if it's not running.
if ! pgrep any_proxy >/dev/null; then
debug "Starting any_proxy."
nohup any_proxy -l=:$ANY_PROXY_PORT -p=$REMOTE_PROXY -f=/var/log/any_proxy.log -s=1 -R=0 -r=0 -v=1 >/dev/null 2>&1 &
fi
# Create nat chains called proxy and proxy-docker if they don't exist.
if ! iptables -t nat -nL proxy >/dev/null 2>&1; then
debug "Adding proxy and proxy-docker chains to iptables."
iptables -t nat -N proxy
iptables -t nat -N proxy-docker
fi
for port in $PORTS; do
# In the output chain, redirect all 22, 80 and 443 traffic to the proxy chains.
iptables_add_if_not_present -t nat -A OUTPUT -p tcp -m tcp --dport $port -j proxy
# Do the same for all traffic originating from docker hosts in the prerouting chain.
iptables_add_if_not_present -t nat -A PREROUTING -p tcp -s 172.16.0.0/12 --dport $port -j proxy-docker
done
# In the proxy chains, ignore packets whose destination is a local subnet.
for subnet in $LOCAL_SUBNETS; do
iptables_add_if_not_present -t nat -A proxy -d $subnet -j RETURN
iptables_add_if_not_present -t nat -A proxy-docker -d $subnet -j RETURN
done
# If a packet gets to the end of the proxy chain, redirect it to port 3129
iptables_add_if_not_present -t nat -A proxy -p tcp -j REDIRECT --to-ports $ANY_PROXY_PORT
# If a packet gets to the end of the proxy-docker chain, DNAT it to the host any_proxy.
iptables_add_if_not_present -t nat -A proxy-docker -p tcp -j DNAT --to-destination 172.17.0.1:3129
# Redirect 8.8.8.8 to primary device DNS for docker
iptables_add_if_not_present -t nat -A PREROUTING -p udp -d 8.8.8.8 --dport 53 -j DNAT --to-destination $DEFAULT_DNS
# Set ntp server to flight centre one in time sync config.
# @TODO Does this even work?
if ! grep -q flitech /etc/systemd/timesyncd.conf; then
debug "Adding ntp host to timesyncd.conf."
echo 'NTP=time.au.flitech.net' >> /etc/systemd/timesyncd.conf
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment