6
Makefile
6
Makefile
|
@ -1,3 +1,5 @@
|
||||||
|
SHELL := /bin/bash
|
||||||
|
|
||||||
VERSION=$(shell git describe --tags)
|
VERSION=$(shell git describe --tags)
|
||||||
BUILD=$(shell git rev-parse --short HEAD)
|
BUILD=$(shell git rev-parse --short HEAD)
|
||||||
PROJ := $(shell basename "$(PWD)")
|
PROJ := $(shell basename "$(PWD)")
|
||||||
|
@ -25,13 +27,13 @@ build-unix:
|
||||||
$(shell export GOOS=$(GOOS); export GOARCH=$(GOARCH); go build ${LDFLAGS} -o dist/$(PROJ)_$(VERSION)_$(GOOS)_$(GOARCH)/$(PROJ))))
|
$(shell export GOOS=$(GOOS); export GOARCH=$(GOARCH); go build ${LDFLAGS} -o dist/$(PROJ)_$(VERSION)_$(GOOS)_$(GOARCH)/$(PROJ))))
|
||||||
|
|
||||||
build-win:
|
build-win:
|
||||||
$(shell export GOOS=windows; export GOARCH=arm64; go build ${LDFLAGS} -o dist/$(PROJ)_$(VERSION)_windows_arm64/$(PROJ).exe)
|
$(shell export GOOS=windows; export GOARCH=amd64; go build ${LDFLAGS} -o dist/$(PROJ)_$(VERSION)_windows_amd64/$(PROJ).exe)
|
||||||
|
|
||||||
build-mac-m1:
|
build-mac-m1:
|
||||||
$(shell export GOOS=darwin; export GOARCH=arm64; go build ${LDFLAGS} -o dist/$(PROJ)_$(VERSION)_darwin_arm64/$(PROJ))
|
$(shell export GOOS=darwin; export GOARCH=arm64; go build ${LDFLAGS} -o dist/$(PROJ)_$(VERSION)_darwin_arm64/$(PROJ))
|
||||||
|
|
||||||
build-zip:
|
build-zip:
|
||||||
cd dist; for f in * ;do tar -czf $${f}.tar.gz $${f}; done
|
cd dist; for f in * ;do if ! [[ $$f =~ "gz" ]] ; then tar -czf $${f}.tar.gz $${f}; fi done
|
||||||
|
|
||||||
binary: build-unix build-win build-mac-m1
|
binary: build-unix build-win build-mac-m1
|
||||||
|
|
||||||
|
|
20
README.md
20
README.md
|
@ -19,16 +19,20 @@ Available Commands:
|
||||||
Flags:
|
Flags:
|
||||||
-a, --all show local ip
|
-a, --all show local ip
|
||||||
-c, --cell show cell, must used with --list
|
-c, --cell show cell, must used with --list
|
||||||
|
--cron run as cron service
|
||||||
-h, --help help for myip
|
-h, --help help for myip
|
||||||
-u, --host string hostname to connect (default "kumoly.io")
|
-u, --host string hostname to connect (default "kumoly.io")
|
||||||
-l, --list show list
|
-l, --list show list
|
||||||
|
-n, --name string tell the server who you are
|
||||||
--no-pub disable PublicIP
|
--no-pub disable PublicIP
|
||||||
-p, --port string server port to connect (default "5080")
|
-p, --port string server port to connect (default "5080")
|
||||||
--secure use https
|
--secure use https
|
||||||
|
-s, --spec string hostname to connect (default "0 */5 * * * *")
|
||||||
-t, --title show title, used with --list
|
-t, --title show title, used with --list
|
||||||
-v, --version version for myip
|
-v, --version version for myip
|
||||||
|
|
||||||
Use "myip [command] --help" for more information about a command.
|
Use "myip [command] --help" for more information about a command.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
@ -40,6 +44,12 @@ docker pull hub.kumoly.io/tools/myip:latest
|
||||||
docker run --name myip-server -d -p 5080:5080 --restart=always hub.kumoly.io/tools/myip
|
docker run --name myip-server -d -p 5080:5080 --restart=always hub.kumoly.io/tools/myip
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Client:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker pull hub.kumoly.io/tools/myip:latest
|
||||||
|
docker run --name myip -d --restart=always hub.kumoly.io/tools/myip myip --cron --spec "@hourly"
|
||||||
|
```
|
||||||
|
|
||||||
## Cron
|
## Cron
|
||||||
|
|
||||||
|
@ -52,6 +62,16 @@ Hours | Yes | 0-23 | * / , -
|
||||||
Day of month | Yes | 1-31 | * / , - ?
|
Day of month | Yes | 1-31 | * / , - ?
|
||||||
Month | Yes | 1-12 or JAN-DEC | * / , -
|
Month | Yes | 1-12 or JAN-DEC | * / , -
|
||||||
Day of week | Yes | 0-6 or SUN-SAT | * / , - ?
|
Day of week | Yes | 0-6 or SUN-SAT | * / , - ?
|
||||||
|
|
||||||
|
Entry | Description | Equivalent To
|
||||||
|
----- | ----------- | -------------
|
||||||
|
@yearly (or @annually) | Run once a year, midnight, Jan. 1st | 0 0 0 1 1 *
|
||||||
|
@monthly | Run once a month, midnight, first of month | 0 0 0 1 * *
|
||||||
|
@weekly | Run once a week, midnight between Sat/Sun | 0 0 0 * * 0
|
||||||
|
@daily (or @midnight) | Run once a day, midnight | 0 0 0 * * *
|
||||||
|
@hourly | Run once an hour, beginning of hour | 0 0 * * * *
|
||||||
|
|
||||||
|
@every <duration>
|
||||||
```
|
```
|
||||||
|
|
||||||
**Duration**: `myip -altc --cron --spec "@every 5m"`
|
**Duration**: `myip -altc --cron --spec "@every 5m"`
|
||||||
|
|
|
@ -8,8 +8,10 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/robfig/cron/v3"
|
"github.com/robfig/cron/v3"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -32,6 +34,12 @@ var (
|
||||||
cronSpec string
|
cronSpec string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Iface struct {
|
||||||
|
IP string
|
||||||
|
HardwareAddr string
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
var ClientCmd = &cobra.Command{
|
var ClientCmd = &cobra.Command{
|
||||||
Use: "myip",
|
Use: "myip",
|
||||||
Short: "myip is a easy way to get public ip of current system.",
|
Short: "myip is a easy way to get public ip of current system.",
|
||||||
|
@ -110,8 +118,8 @@ func Scan() error {
|
||||||
if !noPub {
|
if !noPub {
|
||||||
fmt.Fprintf(w, "\t%v\t%v\t\n", "PublicIP", ip)
|
fmt.Fprintf(w, "\t%v\t%v\t\n", "PublicIP", ip)
|
||||||
}
|
}
|
||||||
for k, v := range local {
|
for _, iface := range local {
|
||||||
fmt.Fprintf(w, "\t%v\t%v\t\n", k, v)
|
fmt.Fprintf(w, "\t%v\t%v\t\n", iface.Name, iface.IP)
|
||||||
}
|
}
|
||||||
return w.Flush()
|
return w.Flush()
|
||||||
|
|
||||||
|
@ -120,7 +128,7 @@ func Scan() error {
|
||||||
fmt.Printf("%v ", ip)
|
fmt.Printf("%v ", ip)
|
||||||
}
|
}
|
||||||
for _, v := range local {
|
for _, v := range local {
|
||||||
fmt.Printf("%v ", v)
|
fmt.Printf("%v ", v.IP)
|
||||||
}
|
}
|
||||||
fmt.Printf("\n")
|
fmt.Printf("\n")
|
||||||
}
|
}
|
||||||
|
@ -128,8 +136,8 @@ func Scan() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetLocalIP() (map[string]string, error) {
|
func GetLocalIP() ([]Iface, error) {
|
||||||
ret := map[string]string{}
|
ret := []Iface{}
|
||||||
ifaces, err := net.Interfaces()
|
ifaces, err := net.Interfaces()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
|
@ -161,10 +169,17 @@ func GetLocalIP() (map[string]string, error) {
|
||||||
// continue
|
// continue
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
ret[i.Name] = ip.String()
|
ret = append(ret, Iface{
|
||||||
|
IP: ip.String(),
|
||||||
|
Name: i.Name,
|
||||||
|
HardwareAddr: i.HardwareAddr.String(),
|
||||||
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sort.Slice(ret, func(i, j int) bool {
|
||||||
|
return ret[i].Name < ret[j].Name
|
||||||
|
})
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +188,11 @@ func GetPublicIP() (string, error) {
|
||||||
if secure {
|
if secure {
|
||||||
protocol = "https://"
|
protocol = "https://"
|
||||||
}
|
}
|
||||||
res, err := http.Get(protocol + host + ":" + port + "?name=" + name)
|
req, _ := http.NewRequest("GET", protocol+host+":"+port+"?name="+name, nil)
|
||||||
|
client := &http.Client{
|
||||||
|
Timeout: time.Second * 10,
|
||||||
|
}
|
||||||
|
res, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return "", err
|
return "", err
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -31,6 +32,27 @@ func init() {
|
||||||
|
|
||||||
func StartServer() error {
|
func StartServer() error {
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ip := GetIP(r)
|
||||||
|
fmt.Fprint(w, ip+"\n")
|
||||||
|
|
||||||
|
// logging
|
||||||
|
user := r.URL.Query().Get("name")
|
||||||
|
if user == "" {
|
||||||
|
user = r.URL.String()
|
||||||
|
}
|
||||||
|
host, _, _ := net.SplitHostPort(r.RemoteAddr)
|
||||||
|
log.Printf("%s %s %s %s %s\n", time.Now().Format("2006-01-02-15:04:05"), host, ip, user, r.Header.Get("User-Agent"))
|
||||||
|
})
|
||||||
|
|
||||||
|
err := http.ListenAndServe(addr+":"+port, simpleLogger(http.DefaultServeMux))
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetIP(r *http.Request) string {
|
||||||
ip := r.Header.Get("X-Real-Ip")
|
ip := r.Header.Get("X-Real-Ip")
|
||||||
if ip == "" {
|
if ip == "" {
|
||||||
ip = r.Header.Get("X-Forwarded-For")
|
ip = r.Header.Get("X-Forwarded-For")
|
||||||
|
@ -42,16 +64,7 @@ func StartServer() error {
|
||||||
ip = r.RemoteAddr
|
ip = r.RemoteAddr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r.Header.Add("X-Myip", ip)
|
return ip
|
||||||
fmt.Fprint(w, ip+"\n")
|
|
||||||
})
|
|
||||||
|
|
||||||
err := http.ListenAndServe(addr+":"+port, simpleLogger(http.DefaultServeMux))
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func simpleLogger(handler http.Handler) http.Handler {
|
func simpleLogger(handler http.Handler) http.Handler {
|
||||||
|
@ -63,11 +76,7 @@ func simpleLogger(handler http.Handler) http.Handler {
|
||||||
// fmt.Println(name, value)
|
// fmt.Println(name, value)
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
user := r.URL.Query().Get("name")
|
// log.Printf("%s %s %s %s\n", r.RemoteAddr, r.Method, r.URL, r.Header.Get("User-Agent"))
|
||||||
if user == "" {
|
|
||||||
user = r.URL.String()
|
|
||||||
}
|
|
||||||
log.Printf("%s %s %s %s\n", r.RemoteAddr, r.Method, user, r.Header.Get("User-Agent"))
|
|
||||||
handler.ServeHTTP(w, r)
|
handler.ServeHTTP(w, r)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue