Where did 255 come from? Did you confuse this with protocol numbers? Also, what made you settle on default values? I think it's ok to be more pedantic about the types here. I was already working on rewriting this when I noticed the port range check was still missing.

What about this?

       protocol = rule.pop("protocol", None)
          min_range = rule.get("port_range_min")
          max_range = rule.get("port_range_max")
          if protocol:
              if (protocol in PROTOCOLS):
                  if ((min_range is not None and max_range is None) or
                      (min_range is None and max_range is not None)):
                      raise exceptions.InvalidInput(
                          error_message="For TCP/UDP rules, cannot wildcard only"
                                        " one end of port range.")
                  if min_range is not None and max_range is not None:
                      if (isinstance(min_range, int) and
                          isinstance(max_range, int)):
                          if min_range > max_range:
                              raise exceptions.InvalidInput(
                                  error_message="port_min_range must be less"
                                                " than or equal to "
                                                " port_max_range.")
                      else:
                          raise exceptions.InvalidInput(
                              error_message="port_min_range and port_max_range "
                                            "must be integers.")