diff --git a/cmd/puppeth/wizard.go b/cmd/puppeth/wizard.go
index 3fdd639f80dff2e9c4a634171f499c98817c9056..5fbc11cb98391b10ac8f03be6ed1eea5380d95b7 100644
--- a/cmd/puppeth/wizard.go
+++ b/cmd/puppeth/wizard.go
@@ -302,8 +302,10 @@ func (w *wizard) readJSON() string {
 }
 
 // readIPAddress reads a single line from stdin, trimming if from spaces and
-// converts it to a network IP address.
-func (w *wizard) readIPAddress() net.IP {
+// returning it if it's convertible to an IP address. The reason for keeping
+// the user input format instead of returning a Go net.IP is to match with
+// weird formats used by ethstats, which compares IPs textually, not by value.
+func (w *wizard) readIPAddress() string {
 	for {
 		// Read the IP address from the user
 		fmt.Printf("> ")
@@ -312,14 +314,13 @@ func (w *wizard) readIPAddress() net.IP {
 			log.Crit("Failed to read user input", "err", err)
 		}
 		if text = strings.TrimSpace(text); text == "" {
-			return nil
+			return ""
 		}
 		// Make sure it looks ok and return it if so
-		ip := net.ParseIP(text)
-		if ip == nil {
+		if ip := net.ParseIP(text); ip == nil {
 			log.Error("Invalid IP address, please retry")
 			continue
 		}
-		return ip
+		return text
 	}
 }
diff --git a/cmd/puppeth/wizard_ethstats.go b/cmd/puppeth/wizard_ethstats.go
index 504d8fd9cb66b8d9027336d96b8fb13f2c6078e8..8bfa1d6e526cb300291cfa2b36807963730811b7 100644
--- a/cmd/puppeth/wizard_ethstats.go
+++ b/cmd/puppeth/wizard_ethstats.go
@@ -18,6 +18,7 @@ package main
 
 import (
 	"fmt"
+	"sort"
 
 	"github.com/ethereum/go-ethereum/log"
 )
@@ -64,17 +65,37 @@ func (w *wizard) deployEthstats() {
 	fmt.Println()
 	fmt.Printf("Keep existing IP %v blacklist (y/n)? (default = yes)\n", infos.banned)
 	if w.readDefaultString("y") != "y" {
-		infos.banned = nil
-
+		// The user might want to clear the entire list, although generally probably not
+		fmt.Println()
+		fmt.Printf("Clear out blacklist and start over (y/n)? (default = no)\n")
+		if w.readDefaultString("n") != "n" {
+			infos.banned = nil
+		}
+		// Offer the user to explicitly add/remove certain IP addresses
+		fmt.Println()
+		fmt.Println("Which additional IP addresses should be blacklisted?")
+		for {
+			if ip := w.readIPAddress(); ip != "" {
+				infos.banned = append(infos.banned, ip)
+				continue
+			}
+			break
+		}
 		fmt.Println()
-		fmt.Println("Which IP addresses should be blacklisted?")
+		fmt.Println("Which IP addresses should not be blacklisted?")
 		for {
-			if ip := w.readIPAddress(); ip != nil {
-				infos.banned = append(infos.banned, ip.String())
+			if ip := w.readIPAddress(); ip != "" {
+				for i, addr := range infos.banned {
+					if ip == addr {
+						infos.banned = append(infos.banned[:i], infos.banned[i+1:]...)
+						break
+					}
+				}
 				continue
 			}
 			break
 		}
+		sort.Strings(infos.banned)
 	}
 	// Try to deploy the ethstats server on the host
 	trusted := make([]string, 0, len(w.servers))