Created
May 26, 2019 10:45
-
-
Save raspi/102a7721f95c0a72d4b848f3477e7568 to your computer and use it in GitHub Desktop.
Generate SystemD .network files for network interface automatically
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -e | |
# Generate SystemD .network files for network interface automatically | |
# (c) Pekka Järvinen 2019- | |
# Check that there are arguments given | |
if [ "$#" -eq 0 ]; then | |
echo "No arguments were given. See $0 --help or $0 -h for usage instructions." 1>&2 | |
exit 1 | |
fi | |
generatedwith=$@ | |
beverbose=no | |
interface=none | |
dhcp="yes" | |
address="" | |
gateway="" | |
dns="" | |
match="iface" | |
priority=10 | |
matchmac="" | |
# Get current default gateway IP | |
read _ _ currentgateway _ < <(ip route list match 0/0) | |
# options may be followed by one colon to indicate they have a required argument | |
if ! options=$(getopt -o hv:i:a:d:m:g:n:p: -l help,verbose,interface:,address:,dhcp:,match:,gateway:,dns:,priority: -- "$@") | |
then | |
# something went wrong, getopt will put out an error message for us | |
exit 1 | |
fi | |
set -- $options | |
# Parse arguments | |
while [ $# -gt 0 ] | |
do | |
case $1 in | |
-h|--help) | |
echo "Usage: $0" | |
echo " -i --interface <interface> Required. for example: eno1" | |
echo " -p --priority 0-n Priority. Defaults to 10. " | |
echo "" | |
echo "Match type (defaults to iface):" | |
echo " -m --match <iface|mac> [Match] definition for example: iface for Name=" | |
echo "" | |
echo "Use DHCP (default: yes):" | |
echo " -d --dhcp <no|yes|ipv4|ipv6> For example: ipv4" | |
echo "" | |
echo "Use static IP address:" | |
echo " -a --address <IPv4|IPv6 with CIDR> For example: 192.168.1.19/24" | |
echo " -g --gateway <Gateway IP Address> Defaults to current GW. For example: 192.168.1.1" | |
echo " -n --dns <DNS IP Address> For example: 192.168.1.1" | |
echo "" | |
echo "Other:" | |
echo " -v --verbose be verbose" | |
echo " -h --help this help" | |
echo "" | |
echo "Examples:" | |
echo " Use static IP:" | |
echo " $0 -i eno1 -d no -a 192.168.1.10/24 --gateway 192.168.1.1 --dns 192.168.1.1" | |
echo " DHCP IPv4:" | |
echo " $0 -i eno1 -d ipv4" | |
echo "" | |
exit 0 | |
;; | |
-v|--verbose) beverbose="yes" ;; | |
-f|--force) force="yes" ;; | |
# for options with required arguments, an additional shift is required | |
-i|--interface) interface="${2//\'/}" ; shift;; | |
-a|--address) address="${2//\'/}" ; shift;; | |
-d|--dhcp) dhcp="${2//\'/}" ; shift;; | |
-m|--match) match="${2//\'/}" ; shift;; | |
-g|--gateway) gateway="${2//\'/}" ; shift;; | |
-n|--dns) dns="${2//\'/}" ; shift;; | |
-p|--priority) priority="${2//\'/}" ; shift;; | |
(--) shift; break;; | |
(-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;; | |
(*) break;; | |
esac | |
shift | |
done | |
# Check arguments for conflicts and errors | |
macfile=/sys/class/net/$interface/address | |
if [ -f "$macfile" ]; then | |
# Get MAC Address of given interface | |
matchmac=$(< $macfile) | |
else | |
echo "Unknown interface: $interface ($macfile)" 1>&2 | |
exit 1 | |
fi | |
case $dhcp in | |
yes|no|ipv6|ipv4) ;; | |
*) echo "Unknown DHCP type: $dhcp. Use yes|no|ipv6|ipv4" 1>&2; exit 1;; | |
esac | |
if [ "$dhcp" != "no" -a "$address" != "" ]; then | |
echo "Can't mix DHCP and static IP config" 1>&2 | |
exit 1 | |
fi | |
if [ "$address" != "" -a ! -z "${address##*/*}" ]; then | |
echo "No CIDR in static IP $address. Use for example 'IP/24' which is 255.255.255.0." 1>&2 | |
exit 1 | |
fi | |
case $match in | |
mac|iface) ;; | |
*) echo "Unknown match type: $match. Use mac|iface." 1>&2; exit 1;; | |
esac | |
# Output the .network file contents to temporary file | |
ofn=$priority-$interface.network | |
ofile=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXXXX")/$ofn | |
echo "# sudo cp -i $ofile /etc/systemd/network/$ofn" > $ofile | |
echo "# -- Generated with $0 $generatedwith" >> $ofile | |
echo -n "# -- At " >> $ofile | |
date --iso-8601=seconds >> $ofile | |
echo "#" >> $ofile | |
# Match | |
echo "[Match]" >> $ofile | |
echo "# Match MAC Address" >> $ofile | |
if [ "$match" != "mac" ]; then | |
echo -n "#" >> $ofile | |
fi | |
echo "MACAddress=$matchmac" >> $ofile | |
echo "# Match name" >> $ofile | |
if [ "$match" != "iface" ]; then | |
echo -n "#" >> $ofile | |
fi | |
echo "Name=${interface}" >> $ofile | |
echo "" >> $ofile | |
# Network | |
echo "[Network]" >> $ofile | |
echo "Description=Interface $interface (network)" >> $ofile | |
echo "# DHCP no|yes|ipv4|ipv6" >> $ofile | |
if [ "$dhcp" == "no" ]; then | |
echo -n "#" >> $ofile | |
fi | |
echo "DHCP=$dhcp" >> $ofile | |
echo "# Static IPv4 or IPv6 address with CIDR" >> $ofile | |
if [ "$dhcp" != "no" ]; then | |
echo -n "#" >> $ofile | |
fi | |
echo "Address=$address" >> $ofile | |
echo "# Generated automatically from current configuration:" >> $ofile | |
for addr in $(ip address show dev $interface | awk '/inet/{print $2}') | |
do | |
echo "#Address=$addr" >> $ofile | |
done | |
echo "# Gateway IP Address" >> $ofile | |
if [ "$gateway" == "" ]; then | |
gateway=$currentgateway | |
fi | |
if [ "$dhcp" != "no" ]; then | |
echo -n "#" >> $ofile | |
fi | |
echo "Gateway=$gateway" >> $ofile | |
echo "# DNS server address" >> $ofile | |
if [ "$dns" == "" ]; then | |
dns=$gateway | |
echo -n "#" >> $ofile | |
fi | |
echo "DNS=$dns" >> $ofile | |
echo "#Domains=home.lan" >> $ofile | |
echo "#DNSDefaultRoute=" >> $ofile | |
echo "# NTP time keeping server" >> $ofile | |
echo "#NTP=$gateway" >> $ofile | |
echo "# Forward packets (req for NAT)" >> $ofile | |
echo "#IPForward=no" >> $ofile | |
echo "#IPMasquerade=" >> $ofile | |
echo "# VLAN ID" >> $ofile | |
echo "#VLAN=1234" >> $ofile | |
echo "#LinkLocalAddressing=no" >> $ofile | |
echo "#LLMNR=no" >> $ofile | |
echo "#LLDP=" >> $ofile | |
echo "# Send LLDP packets" >> $ofile | |
echo "EmitLLDP=nearest-bridge" >> $ofile | |
echo "" >> $ofile | |
# Link | |
echo "[Link]" >> $ofile | |
echo "# Override MAC (spoof)" >> $ofile | |
echo "#MACAddress=" >> $ofile | |
echo "#ARP=no" >> $ofile | |
echo "#Multicast=no" >> $ofile | |
echo "#Unmanaged=no" >> $ofile | |
echo "#RequiredForOnline=yes" >> $ofile | |
echo "" | |
cat $ofile |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment