#!/bin/bash -e # # set-dns-source.sh - Setup Source NAT in firewalld for outgoing DNS traffic # # Version 1.0, latest version, documentation and bugtracker available at: # https://gitlab.lindenaar.net/scripts/freeipa # # Copyright (c) 2018 Frederik Lindenaar # # This script is free software: you can redistribute and/or modify it under the # terms of version 3 of the GNU General Public License as published by the Free # Software Foundation, or (at your option) any later version of the license. # # This script is distributed in the hope that it will be useful but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this program. If not, visit <http://www.gnu.org/licenses/> to download it. case $1 in install) CMD=add ;; remove) CMD=remove ;; *) echo "usage: $0 <install | remove>" exit 1 esac IPV4ADDR=${IPV4ADDR:?Please provide an IPv4 address or set to 'none'} IPV6ADDR=${IPV6ADDR:?Please provide an IPv6 address or set to 'none'} DEV=${DEV:=$( /usr/sbin/ip route | fgrep ${IPV4ADDR:?No IPv4 address provided, please set device manually} | cut -d\ -f3 )} : ${DEV:?No route found for $IPV4ADDR, please check config or set device manually} # inspired by https://blog.sebastien.raveau.name/2009/04/per-process-routing.html # and https://unix.stackexchange.com/questions/389756/how-to-use-snat-with-firewalld-vs-masq for PROTO in ipv4 ipv6; do [ "$PROTO" == ipv6 ] && ADDR="$IPV6ADDR" || ADDR="$IPV4ADDR" if [ -n "$ADDR" -a "$ADDR" != none ]; then for MODE in "" --permanent; do firewall-cmd $MODE --direct --$CMD-rule $PROTO mangle OUTPUT 0 -m owner --uid-owner named -j MARK --set-mark 53 firewall-cmd $MODE --direct --$CMD-rule $PROTO nat POSTROUTING 0 -o $DEV -m mark --mark 53 -j SNAT --to-source $ADDR done fi done