Modify /etc/hosts

Asnyder
Contributor III

I've modified @adamcodega 's script to be used in jamf for modifying the hosts file to block certain sites. I really like this idea but I'm running into a couple errors. This is what I have so far:

#!/bin/bash
# Please test before using in your environment
##########################################################
# Modified from
# https://www.jamf.com/jamf-nation/discussions/18184/how-to-update-host-file-via-composer
#
# Use Jamf Script Parameter 4 for domain (youtube.com) and 5 for subdomain (images.google.com) and 6 for file (/etc/hosts)

# Set base variables
domain=""
subdomain=""
filename=""
SUCCESS=0

# Setup Jamf variables
if [ $4 != "" ] && [ "$domain"="" ]
    then domain="$4"
fi

if [ $4 = "" ] && [ "$domain"="" ]
    then
        echo "No Domain Variable Configured"
        exit 1
fi      

if [$5 != ""] && ["$subdomain"=""]
    then subdomain="$5"
fi

if [$5 = ""] && ["$subdomain"=""]
    then
        echo "No subdomain Variable Configured, continuing anyway."
fi

if [$6 != ""] && ["$filename"=""]
    then filename="$6"
fi

if [$6 = ""] && ["$filename"=""]
    then
        echo "No filename Variable Configured"
        exit 1
fi

#Set Needle Variable
if [$subdomain = ""]
    then
        needle="$domain"
    else 
        needle="$subdomain.$domain"
fi      
# set hostline variable
hostline="127.0.0.1 $needle"

# Determine if the line already exists in /etc/hosts
grep -q "$needle" "$filename"  

# Grep's return error code can then be checked.
if [ $? -eq $SUCCESS ]
then
  exit 0;
else
  # If the line wasn't found, add it using an echo append >>
  echo "$hostline" >> "$filename"
    # Let's recheck to be sure it was added.
    grep -q "$needle" "$filename"

    if [ $? -eq $SUCCESS ]
        then
            exit 0;
        else
            exit 1;
    fi
fi

The errors I'm getting are:

Script result: /Library/Application Support/JAMF/tmp/WebsiteBlock.sh: line 29: [=]: command not found<br/>/Library/Application Support/JAMF/tmp/WebsiteBlock.sh: line 33: [=]: command not found<br/>/Library/Application Support/JAMF/tmp/WebsiteBlock.sh: line 38: [/etc/hosts: No such file or directory<br/>/Library/Application Support/JAMF/tmp/WebsiteBlock.sh: line 42: [/etc/hosts: No such file or directory<br/>grep: : No such file or directory<br/>/Library/Application Support/JAMF/tmp/WebsiteBlock.sh: line 67: : No such file or directory<br/>grep: : No such file or directory<br/>
10 REPLIES 10

rderewianko
Valued Contributor II

Because i'm a bit lazy today.. I took your script into shellcheck, and modified it so that shellcheck didn't complain about anything other than globbing and word splitting. I haven't tested this, but spacing matters, and a lot of what you were doing above your if then statements never finished due to spacing.

[https://gist.github.com/rderewianko/3253c3a5589456d3e23ad137f6e1d30f](Gist)

Asnyder
Contributor III

@rderewianko I've been in three different languages this week and that wasn't helping. When I first started half of it looked like python. I think your link is broken though, It just reopens this page. I'll do the same with spellcheck to look it over.

rderewianko
Valued Contributor II

Wierd! https://gist.github.com/rderewianko/3253c3a5589456d3e23ad137f6e1d30f

Asnyder
Contributor III

Here is the updated script for anyone who wants it. working now.

#!/bin/bash
# Please test before using in your environment
##########################################################
# Modified from
# https://www.jamf.com/jamf-nation/discussions/18184/how-to-update-host-file-via-composer
#
# Use Jamf Script Parameter 4 for domain (google.com)
# 5 for subdomain (images.) and 
# 6 for file (/etc/hosts)

# Set base variables
domain=""
subdomain=""
filename=""
SUCCESS=0

# Setup Jamf variables
if [ "$4" != "" ] && [ "$domain" = "" ] 
   then 
    domain="$4"
fi

if [ "$4" = "" ] && [ "$domain" = "" ]
    then
        echo "No Domain Variable Configured"
        exit 1
fi      

if [ "$5" != "" ] && [ "$subdomain" = "" ]
    then subdomain="$5"
fi

if [ "$5" = "" ] && [ "$subdomain" = "" ]
    then
        echo "No subdomain Variable Configured, continuing anyway."
fi

if [ "$6" != "" ] && [ "$filename" = "" ]
    then filename="$6"
fi

if [ "$6" = "" ] &&  [ "$filename" = "" ]
    then
        echo "No filename Variable Configured"
        exit 1
fi

#Set Needle Variable
if [ "$subdomain" = "" ]
    then
        needle="www.$domain"
    else 
        needle="www.$subdomain.$domain"
fi      
# set hostline variable
hostline="127.0.0.1 $needle"

# Determine if the line already exists in /etc/hosts
grep -q "$needle" "$filename"  

# Grep's return error code can then be checked.
if [ $? -eq $SUCCESS ]
then
  exit 0
else
  # If the line wasn't found, add it using an echo append >>
  echo "$hostline" >> "$filename"
    # Let's recheck to be sure it was added.
    grep -q "$needle" "$filename"

    if [ $? -eq $SUCCESS ]
        then
            sudo dscacheutil -flushcache
            exit 0
        else
            exit 1
    fi
fi

billups_jamf_ad
New Contributor

Sorry, I've never been good at scripting , but would like to deploy this to keep people from using Skype at our office (CEO's sometimes, man..).

I've added in the base variables:

Set base variables

domain="skype.com"
subdomain="web."
filename="/etc/hosts"
SUCCESS=0

And I also added them into the Parameters on the next tab in JAMF.

But when I run the script to try and block "www.skype.com" and "web.skype.com" I get the following hostfile output in the image.

Or is there an aspect to this that I'm missing completely here? Or am I not putting in the proper info?13c16d8720ed47f4ae10365fedca3ebd

Thanks!

mm2270
Legendary Contributor III

@jay.hash The problem is you're adding a period with the subdomain variable (web.), but on this line when it creates the full string to add to the hosts file

needle="www.$subdomain.$domain"

It already has a period after $subdomain So taking the variables $subdomain (web.) + $domain (skype.com), what's getting setup looks like www.web..skype.com with 2 periods.
The solution is to drop the period from your subdomain variable. Just use web by itself and it should come out right.

As for the single space between 127.0.0.1 and the domain string, just change the space in this line
hostline="127.0.0.1 $needle" between 127.0.0.1 and $needle to be a tab in your script instead of a single space. It doesn't really matter if it's just a space, but if you care about how it looks in the hosts file when viewed, make that change and it should end up looking like the other lines.

cesar_pineda
New Contributor III

Excellent script...thanks for sharing...

PhilS
New Contributor III

This still works under macOS 10.15.3 Catalina.

LovelessinSEA
Contributor II

Thanks so much for this script, I added an ip variable to utilize it in a way we could easily add more specific items to the hosts file. Variables 4, 5, 6 go unchanged but added 7 for ip.

#!/bin/bash
# Script is intended to add items to the host file of a machine. 
# Please test before using in your environment
##########################################################
# Modified from
# https://www.jamf.com/jamf-nation/discussions/18184/how-to-update-host-file-via-composer
# Jamf parameters 4-7 are used in this script. 
##########################################################
#
# Use Jamf Script Parameter 4 for domain (google.com)
# 5 for subdomain (images.) and 
# 6 for file (/etc/hosts)
# 7 for ip address

# Set base variables
domain=""
subdomain=""
filename=""
ip=""
SUCCESS=0

# Setup Jamf variables
if [ "$4" != "" ] && [ "$domain" = "" ] 
   then 
    domain="$4"
fi

if [ "$4" = "" ] && [ "$domain" = "" ]
    then
        echo "No Domain Variable Configured"
        exit 1
fi      

if [ "$5" != "" ] && [ "$subdomain" = "" ]
    then subdomain="$5"
fi

if [ "$5" = "" ] && [ "$subdomain" = "" ]
    then
        echo "No subdomain Variable Configured, continuing anyway."
fi

if [ "$6" != "" ] && [ "$filename" = "" ]
    then filename="$6"
fi

if [ "$6" = "" ] &&  [ "$filename" = "" ]
    then
        echo "No filename Variable Configured"
        exit 1
fi

if [ "$7" != "" ] && [ "$ip" = "" ] 
   then 
  ip="$7"
fi

if [ "$7" = "" ] && [ "$ip" = "" ]
  then
    echo "No IP Address Configured"
    exit 1
fi  

#Set Needle Variable
if [ "$subdomain" = "" ]
    then
        needle=".$domain"
    else 
        needle="$subdomain.$domain"
fi      
# set hostline variable
hostline="$ip $needle"

# Determine if the line already exists in /etc/hosts
grep -q "$needle" "$filename"  

# Grep's return error code can then be checked.
if [ $? -eq $SUCCESS ]
then
  exit 0
else
  # If the line wasn't found, add it using an echo append >>
  echo "$hostline" >> "$filename"
    # Let's recheck to be sure it was added.
    grep -q "$needle" "$filename"

    if [ $? -eq $SUCCESS ]
        then
            sudo dscacheutil -flushcache
            exit 0
        else
            exit 1
    fi
fi

abuehler
New Contributor III

Thanks very much for that script.
I just wonder, if it would be possible to add a function to also remove a specific entry from the hosts file?
I need to temporarily change a host entry for testing purposes. Removing that entry using the same script would be a very elegant solution (changing just one variable from, let's say "add" to "remove" and then running the same policy again to remove the line from all scoped computers).

Unfortunately, my scripting skills are not good enough for something like that...