예제 #1
0
func ExampleNew() {
	ip := net.IPv4(byte(203), byte(43), byte(55), byte(2))
	subdomain := "foo.com"
	expires := time.Now().Add(15 * time.Minute)
	secret := "turnip4tea"
	fmt.Println(hostname.New(ip, subdomain, expires, secret))
}
예제 #2
0
func TestEncodeDecode(t *testing.T) {
	ip := net.IPv4(byte(203), byte(43), byte(55), byte(2))
	subdomain := "foo.com"
	expires := time.Now().Add(15 * time.Minute)
	secret := "turnip4tea"
	// encode
	fqdn := hostname.New(ip, subdomain, expires, secret)
	// decode
	ip2, expires2, _, err := hostname.Decode(fqdn, secret, subdomain)
	if err != nil {
		t.Fatalf("Error when creating hostname: %v", err)
	}
	if ip.String() != ip2.String() {
		t.Fatalf("Incorrect IP - got %v but was expecting %v", ip, ip2)
	}
	if expires.Unix() != expires2.Unix() {
		t.Fatalf("Incorrect Expiry - got %v but was expecting %v", expires, expires2)
	}
}
예제 #3
0
func main() {

	arguments, err := docopt.Parse(usage, nil, true, version, false, true)
	if err != nil {
		fmt.Println("Error parsing command line arguments!")
		os.Exit(1)
	}

	// Validate IP
	ipString := arguments["IP"].(string)
	ip := net.ParseIP(ipString)
	if ip == nil {
		fmt.Fprintf(os.Stderr, "create-hostname: ERR 64: Invalid IP '%s'\n", ipString)
		os.Exit(64)
	}
	ip = ip.To4()
	if ip == nil {
		fmt.Fprintf(os.Stderr, "create-hostname: ERR 65: IPv6 given for IP (should be IPv4) '%s'\n", ipString)
		os.Exit(65)
	}

	// TODO: Validate SUBDOMAIN
	subdomain := arguments["SUBDOMAIN"].(string)

	// Validate EXPIRES
	expiresString := arguments["EXPIRES"].(string)
	expires, err := time.Parse(time.RFC3339Nano, expiresString)
	if err != nil {
		fmt.Fprintf(os.Stderr, "create-hostname: ERR 67: Invalid EXPIRES '%s'\n", expiresString)
		os.Exit(67)
	}

	// TODO: Validate SECRET
	secret := arguments["SECRET"].(string)

	name := hostname.New(ip, subdomain, expires, secret)
	fmt.Println(name)
}
예제 #4
0
// NewLocalServer creates a WebHookServer that listens on publicIP, publicPort
// and uses stateless-dns-server to obtain a hostname.
//
// If networkInterface is non-empty and localPort is non-zero then server will
// listen on the localPort for the given networkInterface. This is useful if
// running inside a container.
func NewLocalServer(
	publicIP []byte,
	publicPort int,
	networkInterface string,
	localPort int,
	subdomain, dnsSecret, tlsCert, tlsKey string,
	expiration time.Duration,
) (*LocalServer, error) {
	s := &LocalServer{
		hooks: make(map[string]http.Handler),
	}

	// Address that we should be listening on
	localAddress := net.TCPAddr{
		IP:   publicIP,
		Port: publicPort,
	}
	if localPort != 0 {
		localAddress.Port = localPort
	}

	// If network interface is specified we listen to that, instead of the public
	// IP address. This is necessary when running inside a docker container where
	// the local network interface isn't assigned to a public IP.
	if networkInterface != "" {
		iface, err := net.InterfaceByName(networkInterface)
		if err != nil {
			return nil, fmt.Errorf(
				"Unable to find interface: %s, error: %s", networkInterface, err,
			)
		}
		addrs, err := iface.Addrs()
		if err != nil {
			return nil, fmt.Errorf(
				"Couldn't list addresses of interface: %s, error: %s", networkInterface, err,
			)
		}
		gotIP := false
		for _, addr := range addrs {
			if a, ok := addr.(*net.IPNet); ok && a.IP.To4() != nil {
				localAddress.IP = a.IP.To4()
				gotIP = true
				break
			}
		}
		if !gotIP {
			return nil, fmt.Errorf("Interface: %s has no IPv4 address", networkInterface)
		}
	}

	// Setup server
	s.server = &graceful.Server{
		Timeout: 35 * time.Second,
		Server: &http.Server{
			Addr:    localAddress.String(),
			Handler: http.HandlerFunc(s.handle),
		},
		NoSignalHandling: true,
	}

	// Setup server TLS configuration
	if tlsCert != "" && tlsKey != "" {
		cert, err := tls.X509KeyPair(
			[]byte(tlsCert),
			[]byte(tlsKey),
		)
		if err != nil {
			return nil, err
		}
		s.server.TLSConfig = &tls.Config{
			NextProtos:   []string{"http/1.1"},
			Certificates: []tls.Certificate{cert},
		}
	}

	// Construct hostname (using stateless-dns-go)
	host := hostname.New(
		publicIP,
		subdomain,
		time.Now().Add(expiration),
		dnsSecret,
	)

	// Construct URL
	proto := "http"
	port := ""
	if s.server.TLSConfig != nil {
		proto = "https"
		if publicPort != 443 {
			port = fmt.Sprintf(":%d", publicPort)
		}
	} else {
		if publicPort != 80 {
			port = fmt.Sprintf(":%d", publicPort)
		}
	}
	s.url = proto + "://" + host + port + "/"

	return s, nil
}